add CRASHREPORT directly to browser
add CRASHREPORT for Windows
add ^P info to report (via DUMPLOG)
new options: crash_email, crash_name, crash_urlmax
new game command: #bugreport
new config option: CRASHREPORT_EXEC_NOSTDERR
new command line option: --bidshow
deleted helper scripts:
NetHackCrashReport.Javascript
nhcrashreport.lua
misc:
update CRASHREPORTURL (will need to be updated before release)
update bitrot in winchain
winchain for Windows
add missing synch_wait for NetHackW --showpaths
add PANICTRACE (and CRASHREPORT) in mdlib.c:build_opts
missing:
packaging (Windows needs the pdb file)
no testing with MSVC command line build
port status:
linux: working, but glibc's backtrace doesn't show static functions
Windows VS: working. pdb file is large - looking into options
MacOS: working
msdos: not supported
VMS: not supported
MSVC: planned, but not attempted
MSYS2: working, but libbacktrace not showing symbols (yet?)
This commit is contained in:
@@ -163,6 +163,9 @@ autounlock when attempting to open a locked door or loot [Apply-Key]
|
|||||||
omitted or skipped and Apply-Key is omitted or you aren't
|
omitted or skipped and Apply-Key is omitted or you aren't
|
||||||
carrying an unlocking tool or you decline to use one
|
carrying an unlocking tool or you decline to use one
|
||||||
boulder override the default boulder symbol [`]
|
boulder override the default boulder symbol [`]
|
||||||
|
crash_email email address to use when filling in crash reports []
|
||||||
|
crash_name name to use when filling in crash reports []
|
||||||
|
crash_urlmax length of longest url we can generate for a crash report []
|
||||||
disclose the types of information you want [ni na nv ng nc no]
|
disclose the types of information you want [ni na nv ng nc no]
|
||||||
offered at the end of the game
|
offered at the end of the game
|
||||||
(space separated list of two-character values;
|
(space separated list of two-character values;
|
||||||
|
|||||||
@@ -1222,6 +1222,10 @@ Toggle the
|
|||||||
.op autopickup
|
.op autopickup
|
||||||
option on/off.
|
option on/off.
|
||||||
Default key is \(oq@\(cq.
|
Default key is \(oq@\(cq.
|
||||||
|
.lp "#bugreport"
|
||||||
|
Bring up a browser window to submit a report to the NetHack Development Team.
|
||||||
|
Can be disabled at the time the program is built; when enabled,
|
||||||
|
CRASHREPORTURL must be set in the system configuration file.
|
||||||
.lp "#call "
|
.lp "#call "
|
||||||
Call (name) a monster, or an object in inventory, on the floor,
|
Call (name) a monster, or an object in inventory, on the floor,
|
||||||
or in the discoveries list, or add an annotation for the
|
or in the discoveries list, or add an annotation for the
|
||||||
@@ -4910,6 +4914,22 @@ window, windowframe, windowtext).
|
|||||||
If NetHack can, it should wrap long lines of text if they don't fit in
|
If NetHack can, it should wrap long lines of text if they don't fit in
|
||||||
the visible area of the window.
|
the visible area of the window.
|
||||||
.hn 2
|
.hn 2
|
||||||
|
Crash Report Options
|
||||||
|
.pg
|
||||||
|
Please note that NetHack does not send \fBany\fP information off your
|
||||||
|
computer unless you manually click submit on a form.
|
||||||
|
.si
|
||||||
|
.lp "OPTION=crash_email:\fIemail_address\fP
|
||||||
|
.lp "OPTION=crash_name:\fIyour_name\fP
|
||||||
|
.ei
|
||||||
|
These options are used only to save you some typing on the crash
|
||||||
|
report and #bugreport forms.
|
||||||
|
.si
|
||||||
|
.lp "OPTION=crash_urlmax:\fIbytes\fP
|
||||||
|
.ei
|
||||||
|
This option is used to limit the length of the URLs generated and is only
|
||||||
|
needed if your browser cannot handle arbitrarily long URLs.
|
||||||
|
.hn 2
|
||||||
Platform-specific Customization options
|
Platform-specific Customization options
|
||||||
.pg
|
.pg
|
||||||
Here are explanations of options that are used by specific platforms or ports
|
Here are explanations of options that are used by specific platforms or ports
|
||||||
@@ -6008,10 +6028,11 @@ large unless it is actively maintained.
|
|||||||
.
|
.
|
||||||
.lp
|
.lp
|
||||||
CRASHREPORTURL\ =\ If set to
|
CRASHREPORTURL\ =\ If set to
|
||||||
\f(CRhttps://www.nethack.org/common/contact.html\fP
|
\f(CRhttps://www.nethack.org/links/cr-37BETA.html\fP
|
||||||
and support is compiled in, brings up a browser window populated with
|
and support is compiled in, brings up a browser window pre-populated with
|
||||||
the information needed to report a problem if the game panics or ends
|
the information needed to report a problem if the game panics or ends
|
||||||
up in an internally inconsistent state.
|
up in an internally inconsistent state, or if the #bugreport command is
|
||||||
|
invoked.
|
||||||
.hn 1
|
.hn 1
|
||||||
Scoring
|
Scoring
|
||||||
.pg
|
.pg
|
||||||
|
|||||||
@@ -26,6 +26,8 @@
|
|||||||
|
|
||||||
\newcommand{\elist}{\end{list}}
|
\newcommand{\elist}{\end{list}}
|
||||||
|
|
||||||
|
\hyphenation{CRASHREPORTURL}
|
||||||
|
|
||||||
% this will make \tt underscores look better, but requires that
|
% this will make \tt underscores look better, but requires that
|
||||||
% math subscripts will never be used in this document
|
% math subscripts will never be used in this document
|
||||||
\catcode`\_=12
|
\catcode`\_=12
|
||||||
@@ -1332,6 +1334,12 @@ Show your attributes. Default key is `{\tt \^{}X}'.
|
|||||||
\item[\tb{\#autopickup}]
|
\item[\tb{\#autopickup}]
|
||||||
Toggle the {\it autopickup\/} option. Default key is `{\tt @}'.
|
Toggle the {\it autopickup\/} option. Default key is `{\tt @}'.
|
||||||
%.lp
|
%.lp
|
||||||
|
\item[\tb{\#bugreport}]
|
||||||
|
Bring up a browser window to submit a report to the {\it NetHack Development
|
||||||
|
Team}.
|
||||||
|
Can be disabled at the time the program is built; when enabled,
|
||||||
|
CRASHREPORTURL must be set in the system configuration file.
|
||||||
|
%.lp
|
||||||
\item[\tb{\#call}]
|
\item[\tb{\#call}]
|
||||||
Call (name) a monster, or an object in inventory, on the floor,
|
Call (name) a monster, or an object in inventory, on the floor,
|
||||||
or in the discoveries list, or add an annotation for the
|
or in the discoveries list, or add an annotation for the
|
||||||
@@ -5420,6 +5428,31 @@ If {\it NetHack\/} can, it should wrap long lines of text if they don't fit
|
|||||||
in the visible area of the window.
|
in the visible area of the window.
|
||||||
\elist
|
\elist
|
||||||
|
|
||||||
|
%.hn 2
|
||||||
|
\subsection*{Crash Report Options}
|
||||||
|
%.pg
|
||||||
|
|
||||||
|
Please note that NetHack does not send {\textbf any} information off your
|
||||||
|
computer unless you manually click submit on a form.
|
||||||
|
%.si
|
||||||
|
\blist{}
|
||||||
|
%.lp
|
||||||
|
\item[OPTION=crash_email:{\it email_address}]
|
||||||
|
%.lp
|
||||||
|
\item[OPTION=crash_name:{\it your_name}]
|
||||||
|
%.ei
|
||||||
|
\elist
|
||||||
|
These options are used only to save you some typing on the crash
|
||||||
|
report and \#bugreport forms.
|
||||||
|
%.si
|
||||||
|
\blist{}
|
||||||
|
%.lp
|
||||||
|
\item[OPTION=crash_urlmax:{\it bytes}]
|
||||||
|
%.ei
|
||||||
|
\elist
|
||||||
|
This option is used to limit the length of the URLs generated and is only
|
||||||
|
needed if your browser cannot handle arbitrarily long URLs.
|
||||||
|
|
||||||
%.hn 2
|
%.hn 2
|
||||||
\subsection*{Platform-specific Customization options}
|
\subsection*{Platform-specific Customization options}
|
||||||
|
|
||||||
@@ -6616,10 +6649,11 @@ large unless it is actively maintained.
|
|||||||
%.lp
|
%.lp
|
||||||
\item[\ib{CRASHREPORTURL}]
|
\item[\ib{CRASHREPORTURL}]
|
||||||
If set to
|
If set to
|
||||||
{\tt https://www.nethack.org/common/contact.html}
|
{\tt https://www.nethack.org/links/cr-37BETA.html}
|
||||||
and support is compiled in, brings up a browser window populated with
|
and support is compiled in, brings up a browser window populated with
|
||||||
the information needed to report a problem if the game panics or ends
|
the information needed to report a problem if the game panics or ends
|
||||||
up in an internally inconsistent state.
|
up in an internally inconsistent state, or if the \#bugreport command is
|
||||||
|
invoked.
|
||||||
\elist
|
\elist
|
||||||
|
|
||||||
%.hn 1
|
%.hn 1
|
||||||
|
|||||||
@@ -530,3 +530,12 @@
|
|||||||
# Use highlighting in the status lines when it changes?
|
# Use highlighting in the status lines when it changes?
|
||||||
#OPTIONS=hilite_status:hitpoints/30%/bright-magenta/normal
|
#OPTIONS=hilite_status:hitpoints/30%/bright-magenta/normal
|
||||||
|
|
||||||
|
### Crash reports
|
||||||
|
# CRASHREPORTURL must be set in syscf to enable these options.
|
||||||
|
# These identify you in crash reports
|
||||||
|
#OPTIONS=crash_name:Your Name
|
||||||
|
#OPTIONS=crash_email:user@example.com
|
||||||
|
# This limits the size of the URL generated for a crash report. Only
|
||||||
|
# use this if your browser can't handle very long URLs. It should be as
|
||||||
|
# large as possible.
|
||||||
|
#OPTIONS=crash_maxurl:4000.
|
||||||
|
|||||||
@@ -241,12 +241,33 @@
|
|||||||
|
|
||||||
#ifndef CRASHREPORT
|
#ifndef CRASHREPORT
|
||||||
# ifdef MACOS
|
# ifdef MACOS
|
||||||
/* NB: This needs to be a full path unless it's in the playground. */
|
# define CRASHREPORT "/usr/bin/open"
|
||||||
//#define CRASHREPORT "NetHackCrashReport.JavaScript"
|
|
||||||
# endif
|
# endif
|
||||||
# ifdef __linux__
|
# ifdef __linux__
|
||||||
/* NB: This expects to find the nhlua binary as "./nhlua" */
|
# define CRASHREPORT "/usr/bin/xdg-open"
|
||||||
//#define CRASHREPORT "nhcrashreport.lua"
|
/* Define this if the terminal is filled with useless error messages
|
||||||
|
* when the browser launches. */
|
||||||
|
# define CRASHREPORT_EXEC_NOSTDERR
|
||||||
|
# endif
|
||||||
|
# ifdef WIN32
|
||||||
|
# define CRASHREPORT /* builtin helper */
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CRASHREPORT
|
||||||
|
# ifndef DUMPLOG
|
||||||
|
# define DUMPLOG // required to get ^P info
|
||||||
|
# endif
|
||||||
|
# ifdef MACOS
|
||||||
|
# define PANICTRACE
|
||||||
|
# endif
|
||||||
|
# ifdef __linux__
|
||||||
|
# define PANICTRACE
|
||||||
|
# endif
|
||||||
|
// This test isn't quite right: CNG is only available from Windows 2000 on.
|
||||||
|
// But we'll check that at runtime.
|
||||||
|
# ifdef WIN32
|
||||||
|
# define PANICTRACE
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -235,6 +235,11 @@ struct instance_globals_c {
|
|||||||
/* dog.c */
|
/* dog.c */
|
||||||
char catname[PL_PSIZ];
|
char catname[PL_PSIZ];
|
||||||
|
|
||||||
|
/* end.c */
|
||||||
|
char *crash_email; // email for crash reports
|
||||||
|
char *crash_name; // human name for crash reports
|
||||||
|
int crash_urlmax; // maximum length for the url of a crash report
|
||||||
|
|
||||||
/* symbols.c */
|
/* symbols.c */
|
||||||
int currentgraphics;
|
int currentgraphics;
|
||||||
|
|
||||||
|
|||||||
@@ -819,10 +819,12 @@ extern struct kinfo *find_delayed_killer(int);
|
|||||||
extern void dealloc_killer(struct kinfo *);
|
extern void dealloc_killer(struct kinfo *);
|
||||||
extern void save_killers(NHFILE *);
|
extern void save_killers(NHFILE *);
|
||||||
extern void restore_killers(NHFILE *);
|
extern void restore_killers(NHFILE *);
|
||||||
#ifdef CRASHREPORT
|
#if defined(CRASHREPORT)
|
||||||
extern boolean submit_web_report(const char *, char *);
|
extern boolean submit_web_report(int, const char *, const char *);
|
||||||
extern void crashreport_init(int, char *[]);
|
extern void crashreport_init(int, char *[]);
|
||||||
extern void crashreport_bidshow(void);
|
extern void crashreport_bidshow(void);
|
||||||
|
extern boolean swr_add_uricoded(const char *, char **, int *, char *);
|
||||||
|
extern int dobugreport(void);
|
||||||
#endif
|
#endif
|
||||||
extern char *build_english_list(char *);
|
extern char *build_english_list(char *);
|
||||||
#if defined(PANICTRACE) && !defined(NO_SIGNAL)
|
#if defined(PANICTRACE) && !defined(NO_SIGNAL)
|
||||||
@@ -1804,6 +1806,13 @@ extern int dosuspend(void);
|
|||||||
extern void nt_regularize(char *);
|
extern void nt_regularize(char *);
|
||||||
extern int(*nt_kbhit)(void);
|
extern int(*nt_kbhit)(void);
|
||||||
extern void Delay(int);
|
extern void Delay(int);
|
||||||
|
# ifdef CRASHREPORT
|
||||||
|
struct CRctxt;
|
||||||
|
extern struct CRctxt *ctxp;
|
||||||
|
extern int win32_cr_helper(char, struct CRctxt *, void *, int);
|
||||||
|
extern int win32_cr_gettrace(int, char *, int);
|
||||||
|
extern int *win32_cr_shellexecute(const char *);
|
||||||
|
# endif
|
||||||
#endif /* WIN32 */
|
#endif /* WIN32 */
|
||||||
|
|
||||||
#endif /* MICRO || WIN32 */
|
#endif /* MICRO || WIN32 */
|
||||||
@@ -2661,7 +2670,7 @@ extern char *get_sound_effect_filename(int32_t seidint,
|
|||||||
char *buf, size_t bufsz, int32_t);
|
char *buf, size_t bufsz, int32_t);
|
||||||
#endif
|
#endif
|
||||||
extern char *base_soundname_to_filename(char *, char *, size_t, int32_t);
|
extern char *base_soundname_to_filename(char *, char *, size_t, int32_t);
|
||||||
extern void set_voice(struct monst *, int32_t, int32_t, int32_t);
|
extern void set_voice(struct monst *, int32_t, int32_t, int32_t);
|
||||||
extern void sound_speak(const char *);
|
extern void sound_speak(const char *);
|
||||||
|
|
||||||
/* ### sp_lev.c ### */
|
/* ### sp_lev.c ### */
|
||||||
|
|||||||
@@ -418,7 +418,7 @@ enum earlyarg {
|
|||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
, ARG_WINDOWS
|
, ARG_WINDOWS
|
||||||
#endif
|
#endif
|
||||||
#ifdef CRASHREPORT
|
#if defined(CRASHREPORT)
|
||||||
, ARG_BIDSHOW
|
, ARG_BIDSHOW
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -226,6 +226,17 @@ static int optfn_##a(int, int, boolean, char *, char *);
|
|||||||
NHOPTB(confirm, Advanced, 0, opt_out, set_in_game,
|
NHOPTB(confirm, Advanced, 0, opt_out, set_in_game,
|
||||||
On, Yes, No, No, NoAlias, &flags.confirm, Term_False,
|
On, Yes, No, No, NoAlias, &flags.confirm, Term_False,
|
||||||
"ask before hitting tame or peaceful monsters")
|
"ask before hitting tame or peaceful monsters")
|
||||||
|
#ifdef CRASHREPORT
|
||||||
|
NHOPTC(crash_email, Advanced, PL_NSIZ, opt_in, set_in_game,
|
||||||
|
No, Yes, No, No, NoAlias,
|
||||||
|
"email address for reporting")
|
||||||
|
NHOPTC(crash_name, Advanced, PL_NSIZ, opt_in, set_in_game,
|
||||||
|
No, Yes, No, No, NoAlias,
|
||||||
|
"your name for reporting")
|
||||||
|
NHOPTC(crash_urlmax, Advanced, PL_NSIZ, opt_in, set_in_game,
|
||||||
|
No, Yes, No, No, NoAlias,
|
||||||
|
"length of longest url we can generate")
|
||||||
|
#endif
|
||||||
#ifdef CURSES_GRAPHICS
|
#ifdef CURSES_GRAPHICS
|
||||||
NHOPTC(cursesgraphics, Advanced, 70, opt_in, set_in_config,
|
NHOPTC(cursesgraphics, Advanced, 70, opt_in, set_in_config,
|
||||||
No, Yes, No, No, NoAlias,
|
No, Yes, No, No, NoAlias,
|
||||||
|
|||||||
@@ -101,12 +101,7 @@ extern char *windows_exepath(void);
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef __MINGW32__
|
#ifdef __MINGW32__
|
||||||
#if 0
|
|
||||||
#define MD_USE_TMPFILE_S
|
#define MD_USE_TMPFILE_S
|
||||||
#if !defined(__cplusplus)
|
|
||||||
extern errno_t tmpfile_s(FILE * restrict * restrict streamptr);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#
|
#
|
||||||
#ifdef strncasecmp
|
#ifdef strncasecmp
|
||||||
#undef strncasecmp
|
#undef strncasecmp
|
||||||
|
|||||||
@@ -14,8 +14,9 @@ enum wp_ids { wp_tty = 1, wp_X11, wp_Qt, wp_mswin, wp_curses,
|
|||||||
wp_chainin, wp_chainout, wp_safestartup, wp_shim,
|
wp_chainin, wp_chainout, wp_safestartup, wp_shim,
|
||||||
wp_hup, wp_guistubs, wp_ttystubs,
|
wp_hup, wp_guistubs, wp_ttystubs,
|
||||||
#ifdef OUTDATED_STUFF
|
#ifdef OUTDATED_STUFF
|
||||||
, wp_mac, wp_Gem, wp_Gnome, wp_amii, wp_amiv
|
wp_mac, wp_Gem, wp_Gnome, wp_amii, wp_amiv,
|
||||||
#endif
|
#endif
|
||||||
|
wp_trace // XXX do we need this? should chainin/out get an id? TBD
|
||||||
};
|
};
|
||||||
|
|
||||||
/* NB: this MUST match chain_procs below */
|
/* NB: this MUST match chain_procs below */
|
||||||
@@ -107,6 +108,7 @@ extern
|
|||||||
/*
|
/*
|
||||||
* If you wish to only support one window system and not use procedure
|
* If you wish to only support one window system and not use procedure
|
||||||
* pointers, add the appropriate #ifdef below.
|
* pointers, add the appropriate #ifdef below.
|
||||||
|
* XXX which is what?
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define init_nhwindows (*windowprocs.win_init_nhwindows)
|
#define init_nhwindows (*windowprocs.win_init_nhwindows)
|
||||||
@@ -359,7 +361,6 @@ struct chain_procs {
|
|||||||
void (*win_end_menu)(CARGS, winid, const char *);
|
void (*win_end_menu)(CARGS, winid, const char *);
|
||||||
int (*win_select_menu)(CARGS, winid, int, MENU_ITEM_P **);
|
int (*win_select_menu)(CARGS, winid, int, MENU_ITEM_P **);
|
||||||
char (*win_message_menu)(CARGS, char, int, const char *);
|
char (*win_message_menu)(CARGS, char, int, const char *);
|
||||||
void (*win_update_inventory)(CARGS, int);
|
|
||||||
void (*win_mark_synch)(CARGS);
|
void (*win_mark_synch)(CARGS);
|
||||||
void (*win_wait_synch)(CARGS);
|
void (*win_wait_synch)(CARGS);
|
||||||
#ifdef CLIPPING
|
#ifdef CLIPPING
|
||||||
@@ -407,6 +408,8 @@ struct chain_procs {
|
|||||||
void (*win_status_update)(CARGS, int, genericptr_t, int, int, int,
|
void (*win_status_update)(CARGS, int, genericptr_t, int, int, int,
|
||||||
unsigned long *);
|
unsigned long *);
|
||||||
boolean (*win_can_suspend)(CARGS);
|
boolean (*win_can_suspend)(CARGS);
|
||||||
|
void (*win_update_inventory)(CARGS, int);
|
||||||
|
win_request_info *(*win_ctrl_nhwindow)(CARGS, winid, int, win_request_info *);
|
||||||
};
|
};
|
||||||
#endif /* WINCHAIN */
|
#endif /* WINCHAIN */
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ static void dump_enums(void);
|
|||||||
void
|
void
|
||||||
early_init(int argc UNUSED, char *argv[] UNUSED)
|
early_init(int argc UNUSED, char *argv[] UNUSED)
|
||||||
{
|
{
|
||||||
#ifdef CRASHREPORT
|
#if defined(CRASHREPORT)
|
||||||
// Do this as early as possible, but let ports do other things first.
|
// Do this as early as possible, but let ports do other things first.
|
||||||
crashreport_init(argc, argv);
|
crashreport_init(argc, argv);
|
||||||
#endif
|
#endif
|
||||||
@@ -911,7 +911,7 @@ static const struct early_opt earlyopts[] = {
|
|||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
{ ARG_WINDOWS, "windows", 4, TRUE },
|
{ ARG_WINDOWS, "windows", 4, TRUE },
|
||||||
#endif
|
#endif
|
||||||
#ifdef CRASHREPORT
|
#if defined(CRASHREPORT)
|
||||||
{ ARG_BIDSHOW, "bidshow", 7, FALSE },
|
{ ARG_BIDSHOW, "bidshow", 7, FALSE },
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
@@ -935,11 +935,13 @@ argcheck(int argc, char *argv[], enum earlyarg e_arg)
|
|||||||
const char *dashdash = "";
|
const char *dashdash = "";
|
||||||
|
|
||||||
for (idx = 0; idx < SIZE(earlyopts); idx++) {
|
for (idx = 0; idx < SIZE(earlyopts); idx++) {
|
||||||
if (earlyopts[idx].e == e_arg)
|
if (earlyopts[idx].e == e_arg){
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (idx >= SIZE(earlyopts) || argc < 1)
|
if (idx >= SIZE(earlyopts) || argc < 1){
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < argc; ++i) {
|
for (i = 0; i < argc; ++i) {
|
||||||
if (argv[i][0] != '-')
|
if (argv[i][0] != '-')
|
||||||
@@ -1002,10 +1004,12 @@ argcheck(int argc, char *argv[], enum earlyarg e_arg)
|
|||||||
dump_glyphids();
|
dump_glyphids();
|
||||||
return 2;
|
return 2;
|
||||||
#endif
|
#endif
|
||||||
#ifdef CRASHREPORT
|
#if defined(CRASHREPORT)
|
||||||
case ARG_BIDSHOW:
|
case ARG_BIDSHOW:
|
||||||
crashreport_bidshow();
|
crashreport_bidshow();
|
||||||
return 2;
|
return 2;
|
||||||
|
#else
|
||||||
|
#warning "CRASHREPORT CODE NOT INCLUDED"
|
||||||
#endif
|
#endif
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
case ARG_WINDOWS:
|
case ARG_WINDOWS:
|
||||||
|
|||||||
@@ -2558,6 +2558,10 @@ struct ext_func_tab extcmdlist[] = {
|
|||||||
doattributes, IFBURIED, NULL },
|
doattributes, IFBURIED, NULL },
|
||||||
{ '@', "autopickup", "toggle the 'autopickup' option on/off",
|
{ '@', "autopickup", "toggle the 'autopickup' option on/off",
|
||||||
dotogglepickup, IFBURIED, NULL },
|
dotogglepickup, IFBURIED, NULL },
|
||||||
|
#ifdef CRASHREPORT
|
||||||
|
{ '\0', "bugreport", "file a bug report",
|
||||||
|
dobugreport, GENERALCMD | NOFUZZERCMD, NULL },
|
||||||
|
#endif
|
||||||
{ 'C', "call", "name a monster, specific object, or type of object",
|
{ 'C', "call", "name a monster, specific object, or type of object",
|
||||||
docallcmd, IFBURIED, NULL },
|
docallcmd, IFBURIED, NULL },
|
||||||
{ 'Z', "cast", "zap (cast) a spell",
|
{ 'Z', "cast", "zap (cast) a spell",
|
||||||
|
|||||||
@@ -272,6 +272,10 @@ const struct instance_globals_c g_init_c = {
|
|||||||
DUMMY, /* context */
|
DUMMY, /* context */
|
||||||
/* dog.c */
|
/* dog.c */
|
||||||
DUMMY, /* catname */
|
DUMMY, /* catname */
|
||||||
|
/* end.c */
|
||||||
|
NULL, /* crash_email */
|
||||||
|
NULL, /* crash_name */
|
||||||
|
-1, /* crash_urlmax */
|
||||||
/* symbols.c */
|
/* symbols.c */
|
||||||
0, /* currentgraphics */
|
0, /* currentgraphics */
|
||||||
/* files.c */
|
/* files.c */
|
||||||
|
|||||||
559
src/end.c
559
src/end.c
@@ -21,9 +21,9 @@
|
|||||||
|
|
||||||
#ifndef NO_SIGNAL
|
#ifndef NO_SIGNAL
|
||||||
static void done_intr(int);
|
static void done_intr(int);
|
||||||
#if defined(UNIX) || defined(VMS) || defined(__EMX__)
|
# if defined(UNIX) || defined(VMS) || defined(__EMX__)
|
||||||
static void done_hangup(int);
|
static void done_hangup(int);
|
||||||
#endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
static void disclose(int, boolean);
|
static void disclose(int, boolean);
|
||||||
static void get_valuables(struct obj *);
|
static void get_valuables(struct obj *);
|
||||||
@@ -37,6 +37,9 @@ static boolean should_query_disclose_option(int, char *);
|
|||||||
static void dump_plines(void);
|
static void dump_plines(void);
|
||||||
#endif
|
#endif
|
||||||
static void dump_everything(int, time_t);
|
static void dump_everything(int, time_t);
|
||||||
|
#ifdef CRASHREPORT
|
||||||
|
static const char *get_saved_pline(int);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(__BEOS__) || defined(MICRO) || defined(OS2) || defined(WIN32)
|
#if defined(__BEOS__) || defined(MICRO) || defined(OS2) || defined(WIN32)
|
||||||
ATTRNORETURN extern void nethack_exit(int) NORETURN;
|
ATTRNORETURN extern void nethack_exit(int) NORETURN;
|
||||||
@@ -46,9 +49,10 @@ ATTRNORETURN extern void nethack_exit(int) NORETURN;
|
|||||||
|
|
||||||
#define done_stopprint gp.program_state.stopprint
|
#define done_stopprint gp.program_state.stopprint
|
||||||
|
|
||||||
#ifndef PANICTRACE
|
// XXX is there a configuration that still needs this?
|
||||||
#define NH_abort(x) NH_abort_
|
//#ifndef PANICTRACE
|
||||||
#endif
|
//#define NH_abort(x) NH_abort_
|
||||||
|
//#endif
|
||||||
|
|
||||||
#ifdef AMIGA
|
#ifdef AMIGA
|
||||||
#define NH_abort_ Abort(0)
|
#define NH_abort_ Abort(0)
|
||||||
@@ -64,7 +68,8 @@ ATTRNORETURN extern void nethack_exit(int) NORETURN;
|
|||||||
#endif /* !SYSV */
|
#endif /* !SYSV */
|
||||||
#endif /* !AMIGA */
|
#endif /* !AMIGA */
|
||||||
|
|
||||||
#ifdef PANICTRACE
|
/* NB: CRASHREPORT implies PANICTRACE */
|
||||||
|
#if defined(PANICTRACE)
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#ifdef PANICTRACE_LIBC
|
#ifdef PANICTRACE_LIBC
|
||||||
#include <execinfo.h>
|
#include <execinfo.h>
|
||||||
@@ -79,32 +84,30 @@ ATTRNORETURN extern void nethack_exit(int) NORETURN;
|
|||||||
* -requires -g, which may preclude -O on some compilers
|
* -requires -g, which may preclude -O on some compilers
|
||||||
*
|
*
|
||||||
* And the UI: if sysopt.crashreporturl, and defined(CRASHREPORT)
|
* And the UI: if sysopt.crashreporturl, and defined(CRASHREPORT)
|
||||||
* we gather the stacktrace (etc) and launch a helper to submit a bug report
|
* we gather the stacktrace (etc) and launch a browser to submit a bug report
|
||||||
* otherwise we just use stdout. Requires libc for now.
|
* otherwise we just use stdout. Requires libc for now.
|
||||||
*/
|
*/
|
||||||
#ifdef SYSCF
|
#ifdef SYSCF
|
||||||
#define SYSOPT_PANICTRACE_GDB sysopt.panictrace_gdb
|
# define SYSOPT_PANICTRACE_GDB sysopt.panictrace_gdb
|
||||||
#ifdef PANICTRACE_LIBC
|
# ifdef PANICTRACE_LIBC
|
||||||
#define SYSOPT_PANICTRACE_LIBC sysopt.panictrace_libc
|
# define SYSOPT_PANICTRACE_LIBC sysopt.panictrace_libc
|
||||||
|
# else
|
||||||
|
# define SYSOPT_PANICTRACE_LIBC 0
|
||||||
|
# endif
|
||||||
#else
|
#else
|
||||||
#define SYSOPT_PANICTRACE_LIBC 0
|
# define SYSOPT_PANICTRACE_GDB (nh_getenv("NETHACK_USE_GDB") == 0 ? 0 : 2)
|
||||||
#endif
|
# ifdef PANICTRACE_LIBC
|
||||||
#else
|
# define SYSOPT_PANICTRACE_LIBC 1
|
||||||
#define SYSOPT_PANICTRACE_GDB (nh_getenv("NETHACK_USE_GDB") == 0 ? 0 : 2)
|
# else
|
||||||
#ifdef PANICTRACE_LIBC
|
# define SYSOPT_PANICTRACE_LIBC 0
|
||||||
#define SYSOPT_PANICTRACE_LIBC 1
|
# endif
|
||||||
#else
|
|
||||||
#define SYSOPT_PANICTRACE_LIBC 0
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef PANICTRACE
|
|
||||||
static void NH_abort(char *);
|
static void NH_abort(char *);
|
||||||
#endif
|
|
||||||
#ifndef NO_SIGNAL
|
#ifndef NO_SIGNAL
|
||||||
static void panictrace_handler(int);
|
static void panictrace_handler(int);
|
||||||
#endif
|
#endif
|
||||||
static boolean NH_panictrace_libc(char *);
|
static boolean NH_panictrace_libc(void);
|
||||||
static boolean NH_panictrace_gdb(void);
|
static boolean NH_panictrace_gdb(void);
|
||||||
|
|
||||||
#ifndef NO_SIGNAL
|
#ifndef NO_SIGNAL
|
||||||
@@ -171,7 +174,6 @@ panictrace_setsignals(boolean set)
|
|||||||
}
|
}
|
||||||
#endif /* NO_SIGNAL */
|
#endif /* NO_SIGNAL */
|
||||||
|
|
||||||
#ifdef PANICTRACE
|
|
||||||
static void
|
static void
|
||||||
NH_abort(char *why)
|
NH_abort(char *why)
|
||||||
{
|
{
|
||||||
@@ -185,215 +187,394 @@ NH_abort(char *why)
|
|||||||
return;
|
return;
|
||||||
aborting = TRUE;
|
aborting = TRUE;
|
||||||
|
|
||||||
|
#ifdef CRASHREPORT
|
||||||
|
if(!submit_web_report(1, "Panic", why))
|
||||||
|
#endif
|
||||||
|
{
|
||||||
#ifndef VMS
|
#ifndef VMS
|
||||||
if (gdb_prio == libc_prio && gdb_prio > 0)
|
if (gdb_prio == libc_prio && gdb_prio > 0)
|
||||||
gdb_prio++;
|
gdb_prio++;
|
||||||
|
|
||||||
if (gdb_prio > libc_prio) {
|
if (gdb_prio > libc_prio) {
|
||||||
(void) (NH_panictrace_gdb() || (libc_prio && NH_panictrace_libc(why)));
|
(void) (NH_panictrace_gdb() || (libc_prio && NH_panictrace_libc()));
|
||||||
} else {
|
} else {
|
||||||
(void) (NH_panictrace_libc(why) || (gdb_prio && NH_panictrace_gdb()));
|
(void) (NH_panictrace_libc() || (gdb_prio && NH_panictrace_gdb()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* VMS */
|
#else /* VMS */
|
||||||
/* overload otherwise unused priority for debug mode: 1 = show
|
/* overload otherwise unused priority for debug mode: 1 = show
|
||||||
traceback and exit; 2 = show traceback and stay in debugger */
|
traceback and exit; 2 = show traceback and stay in debugger */
|
||||||
/* if (wizard && gdb_prio == 1) gdb_prio = 2; */
|
/* if (wizard && gdb_prio == 1) gdb_prio = 2; */
|
||||||
vms_traceback(gdb_prio);
|
vms_traceback(gdb_prio);
|
||||||
nhUse(libc_prio);
|
nhUse(libc_prio);
|
||||||
|
|
||||||
#endif /* ?VMS */
|
#endif /* ?VMS */
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef NO_SIGNAL
|
#ifndef NO_SIGNAL
|
||||||
panictrace_setsignals(FALSE);
|
panictrace_setsignals(FALSE);
|
||||||
#endif
|
#endif
|
||||||
NH_abort_;
|
NH_abort_;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Build a URL with a query string and try to launch a new browser window
|
|
||||||
* to report from panic() or impossible(). Requires libc support for
|
|
||||||
* the stacktrace. Uses memory on the stack to avoid memory allocation
|
|
||||||
* (but libc can still do anything it wants). */
|
|
||||||
|
|
||||||
/* size of argument list for execve(2) */
|
|
||||||
#define SWR_LINES 20
|
|
||||||
/* max stack frames and header lines (details field) */
|
|
||||||
#define SWR_FRAMES 20
|
|
||||||
#define SWR_ADD(line) {if(xargc<(SWR_LINES-1)) xargv[xargc++] = line;}
|
|
||||||
|
|
||||||
#ifdef CRASHREPORT
|
#ifdef CRASHREPORT
|
||||||
# include <fcntl.h>
|
# include <fcntl.h>
|
||||||
# define HASH_PRAGMA_START \
|
# ifdef WIN32
|
||||||
|
# define HASH_PRAGMA_START
|
||||||
|
# define HASH_PRAGMA_END
|
||||||
|
# else
|
||||||
|
# define HASH_PRAGMA_START \
|
||||||
_Pragma("GCC diagnostic push"); \
|
_Pragma("GCC diagnostic push"); \
|
||||||
_Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
|
_Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
|
||||||
# define HASH_PRAGMA_END _Pragma("GCC diagnostic pop");
|
# define HASH_PRAGMA_END _Pragma("GCC diagnostic pop");
|
||||||
|
# endif
|
||||||
# ifdef MACOS
|
# ifdef MACOS
|
||||||
# include <CommonCrypto/CommonDigest.h>
|
# include <CommonCrypto/CommonDigest.h>
|
||||||
# define HASH_CONTEXT CC_MD4_CTX
|
# define HASH_CONTEXTPTR(CTXP) \
|
||||||
# define HASH_INIT(ctx) CC_MD4_Init(ctx)
|
unsigned char tmp[CC_MD4_DIGEST_LENGTH]; \
|
||||||
# define HASH_UPDATE(ctx, ptr, len) CC_MD4_Update(ctx, ptr, len)
|
CC_MD4_CTX CTXP ## _; \
|
||||||
# define HASH_FINISH(ctx, out) CC_MD4_Final(out, ctx)
|
CC_MD4_CTX *CTXP = &CTXP ## _
|
||||||
# define HASH_RESULT_SIZE CC_MD4_DIGEST_LENGTH
|
# define HASH_INIT(ctxp) !CC_MD4_Init(ctxp)
|
||||||
|
# define HASH_UPDATE(ctx, ptr, len) !CC_MD4_Update(ctx, ptr, len)
|
||||||
|
# define HASH_FINISH(ctxp) !CC_MD4_Final(tmp, ctxp)
|
||||||
|
# define HASH_RESULT_SIZE(ctxp) CC_MD4_DIGEST_LENGTH
|
||||||
|
# define HASH_RESULT(ctx, inp) *inp = (unsigned char *)ctx
|
||||||
|
# define HASH_CLEANUP(ctxp)
|
||||||
|
# define HASH_OFLAGS O_RDONLY
|
||||||
|
# define HASH_BINFILE_DECL char *binfile = argv[0];
|
||||||
|
# ifdef BETA
|
||||||
|
# define HASH_BINFILE \
|
||||||
|
if (!binfile || !*binfile) { \
|
||||||
|
/* If this triggers, investigate CFBundleGetMainBundle */ \
|
||||||
|
/* or CFBundleCopyExecutableURL. */ \
|
||||||
|
raw_print("BETA warning: crashreport_init called without useful info"); \
|
||||||
|
goto skip; \
|
||||||
|
}
|
||||||
|
# else
|
||||||
|
# define HASH_BINFILE() \
|
||||||
|
if (!binfile || !*binfile) { \
|
||||||
|
goto skip; \
|
||||||
|
}
|
||||||
|
# endif
|
||||||
# endif
|
# endif
|
||||||
# ifdef __linux__
|
# ifdef __linux__
|
||||||
# include <openssl/md4.h>
|
# include <openssl/md4.h>
|
||||||
# define HASH_CONTEXT MD4_CTX
|
# define HASH_CONTEXTPTR(CTXP) \
|
||||||
# define HASH_INIT(ctx) MD4_Init(ctx)
|
unsigned char tmp[MD4_DIGEST_LENGTH]; \
|
||||||
# define HASH_UPDATE(ctx, ptr, len) MD4_Update(ctx, ptr, len)
|
MD4_CTX CTXP ## _; \
|
||||||
# define HASH_FINISH(ctx, out) MD4_Final(out, ctx)
|
MD4_CTX *CTXP = &CTXP ## _
|
||||||
# define HASH_RESULT_SIZE MD4_DIGEST_LENGTH
|
# define HASH_INIT(ctxp) !MD4_Init(ctxp)
|
||||||
# endif
|
# define HASH_UPDATE(ctx, ptr, len) !MD4_Update(ctx, ptr, len)
|
||||||
|
# define HASH_FINISH(ctxp) !MD4_Final(tmp, ctxp)
|
||||||
|
# define HASH_RESULT_SIZE(ctxp) MD4_DIGEST_LENGTH
|
||||||
|
# define HASH_RESULT(ctx, inp) *inp = (unsigned char *)ctx
|
||||||
|
# define HASH_CLEANUP(ctxp)
|
||||||
|
# define HASH_OFLAGS O_RDONLY
|
||||||
|
# define HASH_BINFILE_DECL char binfile[PATH_MAX+1];
|
||||||
|
# define HASH_BINFILE() \
|
||||||
|
int len = readlink("/proc/self/exe", binfile, sizeof(binfile)-1); \
|
||||||
|
if (len>0) { \
|
||||||
|
binfile[len] = '\0'; \
|
||||||
|
} else { \
|
||||||
|
goto skip; \
|
||||||
|
}
|
||||||
|
# endif // __linux__
|
||||||
|
# ifdef WIN32
|
||||||
|
/* WIN32 takes too much code and is dependent on OS includes we can't
|
||||||
|
* pull in here, so we call out to code in sys/windows/windsys.c */
|
||||||
|
# define HASH_CONTEXTPTR(CTXP)
|
||||||
|
# define HASH_INIT(ctxp) win32_cr_helper('i',ctxp, NULL, 0)
|
||||||
|
# define HASH_UPDATE(ctxp, ptr, len) win32_cr_helper('u',ctxp, ptr, len)
|
||||||
|
# define HASH_FINISH(ctxp) win32_cr_helper('f',ctxp,NULL,0)
|
||||||
|
# define HASH_CLEANUP(ctxp) win32_cr_helper('c',ctxp, NULL, 0)
|
||||||
|
# define HASH_RESULT_SIZE(ctxp) win32_cr_helper('s',ctxp,NULL,0)
|
||||||
|
# define HASH_RESULT(ctxp, inp) win32_cr_helper('r',ctxp,inp,0)
|
||||||
|
# define HASH_OFLAGS _O_RDONLY | _O_BINARY
|
||||||
|
# define HASH_BINFILE_DECL char *binfile;
|
||||||
|
# define HASH_BINFILE() \
|
||||||
|
if(win32_cr_helper('b',NULL,&binfile,0)){ \
|
||||||
|
goto skip; \
|
||||||
|
}
|
||||||
|
# endif // WIN32
|
||||||
// Binary ID - Use only as a hint to contact.html for recognizing our own
|
// Binary ID - Use only as a hint to contact.html for recognizing our own
|
||||||
// binaries. This is easily spoofed!
|
// binaries. This is easily spoofed!
|
||||||
static char bid[(2*HASH_RESULT_SIZE)+1];
|
static char bid[40];
|
||||||
|
|
||||||
/* ARGSUSED */
|
/* ARGSUSED */
|
||||||
void
|
void
|
||||||
crashreport_init(int argc UNUSED, char *argv[] UNUSED){
|
crashreport_init(int argc UNUSED, char *argv[] UNUSED){
|
||||||
unsigned char tmp[HASH_RESULT_SIZE];
|
static int once=0; if(once++) return; // NetHackW.exe calls us twice
|
||||||
|
HASH_BINFILE_DECL;
|
||||||
HASH_PRAGMA_START
|
HASH_PRAGMA_START
|
||||||
HASH_CONTEXT ctx;
|
HASH_CONTEXTPTR(ctxp);
|
||||||
HASH_INIT(&ctx);
|
if(HASH_INIT(ctxp)) goto skip;
|
||||||
#ifdef MACOS
|
HASH_BINFILE(); // Does "goto skip" on error.
|
||||||
char *binfile = argv[0];
|
|
||||||
if (!binfile || !*binfile) {
|
int fd = open(binfile, HASH_OFLAGS, 0);
|
||||||
# ifdef BETA
|
|
||||||
// If this triggers, investigate CFBundleGetMainBundle
|
|
||||||
// or CFBundleCopyExecutableURL.
|
|
||||||
raw_print("BETA warning: crashreport_init called without useful info");
|
|
||||||
# endif
|
|
||||||
goto skip;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef __linux__
|
|
||||||
char binfile[PATH_MAX+1];
|
|
||||||
int len = readlink("/proc/self/exe", binfile, sizeof(binfile)-1);
|
|
||||||
if (len>0) {
|
|
||||||
binfile[len] = '\0';
|
|
||||||
} else {
|
|
||||||
goto skip;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
int fd = open(binfile, O_RDONLY, 0);
|
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
# ifdef BETA
|
# ifdef BETA
|
||||||
raw_printf("open e=%s",strerror(errno));
|
raw_printf("open e=%s",strerror(errno));
|
||||||
# endif
|
# endif
|
||||||
goto skip;
|
goto skip;
|
||||||
}
|
}
|
||||||
|
|
||||||
int segsize;
|
int segsize;
|
||||||
char segment[4096];
|
unsigned char segment[4096];
|
||||||
while (0 < (segsize = read(fd, segment,sizeof(segment)))) {
|
while (0 < (segsize = read(fd, segment,sizeof(segment)))) {
|
||||||
HASH_UPDATE(&ctx, segment, segsize);
|
if(HASH_UPDATE(ctxp, segment, segsize)) goto skip;
|
||||||
}
|
}
|
||||||
HASH_FINISH(&ctx, tmp);
|
if(segsize < 0) {
|
||||||
|
close(fd);
|
||||||
|
goto skip;
|
||||||
|
}
|
||||||
|
if(HASH_FINISH(ctxp)) goto skip;
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
char *p = bid;
|
char *p = bid;
|
||||||
unsigned char *in = &tmp[0];
|
unsigned char *in;
|
||||||
char cnt=HASH_RESULT_SIZE;
|
HASH_RESULT(ctxp,&in);
|
||||||
|
/* Just in case, make sure not to overflow the bid buffer. */
|
||||||
|
char cnt=min(HASH_RESULT_SIZE(ctxp), (sizeof(bid)-1));
|
||||||
while (cnt--) {
|
while (cnt--) {
|
||||||
p += snprintf(p, HASH_RESULT_SIZE-(p-bid), "%02x",*(in++));
|
p += snprintf(p, HASH_RESULT_SIZE(ctxp) - (p - bid), "%02x", *(in++));
|
||||||
}
|
}
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
return;
|
return;
|
||||||
skip:
|
skip:
|
||||||
strncpy((char *)bid,"unknown",sizeof(bid)-1);
|
strncpy((char *)bid,"unknown",sizeof(bid)-1);
|
||||||
|
HASH_CLEANUP(ctxp);
|
||||||
HASH_PRAGMA_END
|
HASH_PRAGMA_END
|
||||||
}
|
}
|
||||||
#undef HASH_CONTEXT
|
#undef HASH_CONTEXTPTR
|
||||||
#undef HASH_INIT
|
#undef HASH_INIT
|
||||||
#undef HASH_UPDATE
|
#undef HASH_UPDATE
|
||||||
#undef HASH_FINISH
|
#undef HASH_FINISH
|
||||||
|
#undef HASH_CLEANUP
|
||||||
|
#undef HASH_RESULT
|
||||||
#undef HASH_RESULT_SIZE
|
#undef HASH_RESULT_SIZE
|
||||||
#undef HASH_PRAGMA_START
|
#undef HASH_PRAGMA_START
|
||||||
#undef HASH_PRAGMA_END
|
#undef HASH_PRAGMA_END
|
||||||
|
#undef HASH_BINFILE_DECL
|
||||||
|
#undef HASH_BINFILE
|
||||||
|
|
||||||
void
|
void
|
||||||
crashreport_bidshow(void){
|
crashreport_bidshow(void){
|
||||||
raw_print(bid);
|
#if defined(WIN32) && !defined(WIN32CON)
|
||||||
|
if(0==win32_cr_helper('D', ctxp, bid, 0))
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
raw_print(bid);
|
||||||
|
#ifdef WIN32notyet
|
||||||
|
wait_synch();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Build a URL with a query string and try to launch a new browser window
|
||||||
|
* to report from panic() or impossible(). Requires libc support for
|
||||||
|
* the stacktrace. Uses memory on the stack to avoid memory allocation
|
||||||
|
* (on most platforms) (but libc can still do anything it wants). */
|
||||||
|
|
||||||
|
// No theoretial limit for URL length but reality is messy.
|
||||||
|
// This should work on all modern platforms.
|
||||||
|
#ifndef MAX_URL
|
||||||
|
# define MAX_URL 8192
|
||||||
|
#endif
|
||||||
|
#ifndef SWR_FRAMES
|
||||||
|
# define SWR_FRAMES 20
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// mark holds the initial eos; if we can't get the value in
|
||||||
|
// then we can remove the whole item if desired. For other
|
||||||
|
// semantics, caller can handle mark.
|
||||||
|
#define SWR_ADD(str) \
|
||||||
|
utmp = strlen(str); \
|
||||||
|
mark = uend; \
|
||||||
|
if(utmp >= urem) goto full; \
|
||||||
|
strncpy(uend, str, utmp); \
|
||||||
|
uend += utmp; urem -= utmp; \
|
||||||
|
*uend = '\0';
|
||||||
|
|
||||||
|
// NB: on overflow this rolls us back to mark, so if we don't
|
||||||
|
// want to roll back to the last SWR_ADD, update mark before
|
||||||
|
// calling this macro.
|
||||||
|
#define SWR_ADD_URIcoded(str) \
|
||||||
|
if(swr_add_uricoded(str, &uend, &urem, mark))goto full;
|
||||||
|
|
||||||
|
// On overflow, truncate to markp (but only if markp != NULL).
|
||||||
boolean
|
boolean
|
||||||
submit_web_report(const char *msg, char *why){
|
swr_add_uricoded(const char *in, char **out, int *remaining, char *markp){
|
||||||
if (sysopt.crashreporturl) {
|
while(*in){
|
||||||
const char *xargv[SWR_LINES];
|
if(
|
||||||
char version[100];
|
isalnum(*in) ||
|
||||||
char versionstring[200]; // used twice as a temp
|
*in == '_' ||
|
||||||
int xargc = 0;
|
*in == '-' ||
|
||||||
char wholetrace[SWR_LINES*80]; // XXX roughly 71 on MacOS, plus buffer
|
*in == '.' ||
|
||||||
int prelines = 0; // count of lines in trace header
|
*in == '~' // ||
|
||||||
char nbuf[6]; // number buffer
|
){
|
||||||
extern char **environ;
|
**out = *in;
|
||||||
pid_t pid;
|
(*out)++;
|
||||||
|
(*remaining)--;
|
||||||
SWR_ADD(CRASHREPORT);
|
} else if(*in == ' '){
|
||||||
SWR_ADD(sysopt.crashreporturl);
|
**out = '+';
|
||||||
// then pairs of key value
|
(*out)++;
|
||||||
// subject, generate something useful
|
(*remaining)--;
|
||||||
SWR_ADD("subject");
|
} else {
|
||||||
snprintf(version, sizeof(version), "%s report for NetHack %s",
|
if(*remaining <= 3){
|
||||||
msg, version_string(versionstring, sizeof(versionstring)));
|
if(markp) *out = markp, *remaining = 0;
|
||||||
SWR_ADD(version);
|
**out = '\0';
|
||||||
// name: someday, this might be stored in nethackcnf
|
return TRUE;
|
||||||
// email: someday, this might be stored in nethackcnf
|
}
|
||||||
// gitver, pull from version.c
|
int x = snprintf(*out, *remaining, "%%%02X", *in);
|
||||||
SWR_ADD("gitver");
|
*out += x;
|
||||||
SWR_ADD(getversionstring(versionstring, sizeof(versionstring)));
|
*remaining -= x;
|
||||||
// hardware: leave for user
|
|
||||||
// software: leave for user
|
|
||||||
// comments: leave for user
|
|
||||||
// details: stack trace
|
|
||||||
SWR_ADD("details");
|
|
||||||
|
|
||||||
// XXX header for wholetrace - what other info do we want?
|
|
||||||
// NB: prelines not tested against size of SWR_FRAMES.
|
|
||||||
#define SWR_HDR(line) \
|
|
||||||
if (endp<&wholetrace[sizeof(wholetrace)]) { \
|
|
||||||
endp+=snprintf(endp, sizeof(wholetrace)-(endp-wholetrace), "%s\n",line); \
|
|
||||||
prelines++; \
|
|
||||||
}
|
|
||||||
#define SWR_HDRnonl(line) \
|
|
||||||
if (endp<&wholetrace[sizeof(wholetrace)]) { \
|
|
||||||
endp+=snprintf(endp, sizeof(wholetrace)-(endp-wholetrace), "%s",line); \
|
|
||||||
}
|
|
||||||
char *endp = wholetrace;
|
|
||||||
wholetrace[0] = 0;
|
|
||||||
if (why) {
|
|
||||||
SWR_HDR(why);
|
|
||||||
}
|
}
|
||||||
|
in++;
|
||||||
|
if(! *remaining){
|
||||||
|
if(markp) *out = markp, *remaining = 0;
|
||||||
|
**out = '\0';
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
**out = '\0';
|
||||||
|
}
|
||||||
|
return FALSE; // normal return
|
||||||
|
}
|
||||||
|
|
||||||
SWR_HDRnonl("bid: ");
|
static char url[MAX_URL]; // XXX too bad this isn't allocated as needed
|
||||||
SWR_HDR(bid);
|
static int urem = MAX_URL; // adjusted for gc.crash_urlmax below
|
||||||
|
static char *uend = url;
|
||||||
|
static int utmp; // used inside macros
|
||||||
|
static char *mark; // holds previous terminator (generally)
|
||||||
|
|
||||||
|
boolean
|
||||||
|
submit_web_report(int cos, const char *msg, const char *why){
|
||||||
|
urem = (gc.crash_urlmax < 0 || gc.crash_urlmax > MAX_URL)
|
||||||
|
? MAX_URL : min(MAX_URL,gc.crash_urlmax);
|
||||||
|
char temp[200];
|
||||||
|
char temp2[200];
|
||||||
|
int countpp=0; // pre and post traceback lines
|
||||||
|
// URL loaded for creating reports to the NetHack DevTeam
|
||||||
|
// CRASHREPORTURL=https://nethack.org/links/cr-37BETA.html
|
||||||
|
if(!sysopt.crashreporturl) return FALSE;
|
||||||
|
SWR_ADD(sysopt.crashreporturl);
|
||||||
|
/* cos - operation, v - version */
|
||||||
|
snprintf(temp, sizeof(temp), "?cos=%d&v=1",cos);
|
||||||
|
SWR_ADD(temp);
|
||||||
|
|
||||||
|
/* msg==NULL for #bugreport */
|
||||||
|
if(msg){
|
||||||
|
SWR_ADD("&subject=");
|
||||||
|
snprintf(temp, sizeof(temp), "%s report for NetHack %s",
|
||||||
|
msg, version_string(temp2, sizeof(temp2)));
|
||||||
|
SWR_ADD_URIcoded(temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
SWR_ADD("&gitver=");
|
||||||
|
SWR_ADD_URIcoded(getversionstring(temp2, sizeof(temp2)));
|
||||||
|
|
||||||
|
if(gc.crash_name){
|
||||||
|
SWR_ADD("&name=");
|
||||||
|
SWR_ADD_URIcoded(gc.crash_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(gc.crash_email){
|
||||||
|
SWR_ADD("&email=");
|
||||||
|
SWR_ADD_URIcoded(gc.crash_email);
|
||||||
|
}
|
||||||
|
// hardware: leave for user
|
||||||
|
// software: leave for user
|
||||||
|
// comments: leave for user
|
||||||
|
|
||||||
|
SWR_ADD("&details=");
|
||||||
|
if (why) {
|
||||||
|
SWR_ADD_URIcoded(why);
|
||||||
|
SWR_ADD_URIcoded("\n");
|
||||||
|
mark=uend;
|
||||||
|
countpp++;
|
||||||
|
}
|
||||||
|
|
||||||
|
SWR_ADD_URIcoded("bid: ");
|
||||||
|
SWR_ADD_URIcoded(bid);
|
||||||
|
SWR_ADD_URIcoded("\n");
|
||||||
|
mark=uend;
|
||||||
|
countpp++;
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
if(cos==1){
|
||||||
|
#ifdef WIN32
|
||||||
|
count=win32_cr_gettrace(SWR_FRAMES,uend, MAX_URL-(uend-url));
|
||||||
|
uend=eos(url);
|
||||||
|
#else
|
||||||
void *bt[SWR_FRAMES];
|
void *bt[SWR_FRAMES];
|
||||||
int count, x;
|
int x;
|
||||||
char **info, buf[BUFSZ];
|
char **info;
|
||||||
|
|
||||||
count = backtrace(bt, SIZE(bt));
|
count = backtrace(bt, SIZE(bt));
|
||||||
info = backtrace_symbols(bt, count);
|
info = backtrace_symbols(bt, count);
|
||||||
for (x = 0; x < count; x++) {
|
for (x = 0; x < count; x++) {
|
||||||
copynchars(buf, info[x], (int) sizeof buf - 1);
|
copynchars(temp, info[x], (int) sizeof temp - 1 - 1); // \n\0
|
||||||
/* try to remove up to 16 blank spaces by removing 8 twice */
|
/* try to remove up to 16 blank spaces by removing 8 twice */
|
||||||
(void) strsubst(buf, " ", "");
|
(void) strsubst(temp, " ", "");
|
||||||
(void) strsubst(buf, " ", "");
|
(void) strsubst(temp, " ", "");
|
||||||
snprintf(endp, SWR_FRAMES*80-(endp-wholetrace), "[%02lu] %s\n",
|
strncat(temp, "\n", sizeof temp - 1);
|
||||||
(unsigned long) x, buf);
|
# if 0 // __linux__
|
||||||
endp = eos(endp);
|
// not needed for MacOS
|
||||||
|
// XXX is it actually needed for linux? TBD
|
||||||
|
snprintf(temp2, sizeof(temp2), "[%02lu]\n", (unsigned long) x);
|
||||||
|
uend--; // remove the \n we added above
|
||||||
|
SWR_ADD_URIcoded(temp2);
|
||||||
|
# endif // linux
|
||||||
|
SWR_ADD_URIcoded(temp);
|
||||||
|
mark=uend;
|
||||||
}
|
}
|
||||||
*(endp-1) = '\0'; // remove last newline
|
#endif // !WIN32
|
||||||
SWR_ADD(wholetrace);
|
}
|
||||||
|
|
||||||
// detailrows min(actual,50) Guess since we can't know the
|
#ifdef DUMPLOG
|
||||||
|
// config.h turns this on, but make it easy to turn off if needed
|
||||||
|
if(cos==1) {
|
||||||
|
int k;
|
||||||
|
SWR_ADD_URIcoded("Latest messages:\n");
|
||||||
|
mark=uend;
|
||||||
|
countpp++;
|
||||||
|
for(k=0;k<5;k++){
|
||||||
|
const char *line = get_saved_pline(k);
|
||||||
|
if(!line) break;
|
||||||
|
SWR_ADD_URIcoded(line);
|
||||||
|
SWR_ADD_URIcoded("\n");
|
||||||
|
countpp++;
|
||||||
|
mark=uend;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// detailrows: Guess since we can't know the
|
||||||
// width of the window.
|
// width of the window.
|
||||||
SWR_ADD("detailrows");
|
SWR_ADD("&detailrows=");
|
||||||
(void)snprintf(nbuf,sizeof(nbuf),"%d",count+prelines);
|
(void)snprintf(temp,sizeof(temp),"%d",min(count+countpp,30));
|
||||||
SWR_ADD(nbuf);
|
SWR_ADD_URIcoded(temp);
|
||||||
xargv[xargc++] = 0; // terminate array
|
|
||||||
|
|
||||||
pid = fork();
|
full: ;
|
||||||
|
//printf("URL=%ld '%s'\n",strlen(url),url);
|
||||||
|
#ifdef WIN32
|
||||||
|
int *rv = win32_cr_shellexecute(url);
|
||||||
|
// XXX TESTING
|
||||||
|
printf("ShellExecute returned: %p\n",rv); // >32 is ok
|
||||||
|
#else
|
||||||
|
const char *xargv[] = {
|
||||||
|
CRASHREPORT,
|
||||||
|
url,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
int pid = fork();
|
||||||
|
extern char **environ;
|
||||||
if (pid == 0) {
|
if (pid == 0) {
|
||||||
|
#ifdef CRASHREPORT_EXEC_NOSTDERR
|
||||||
|
/* Keep the output clean - firefox spews useless errors on
|
||||||
|
* my system. */
|
||||||
|
(void)close(2);
|
||||||
|
(void)open("/dev/null", O_WRONLY);
|
||||||
|
#endif
|
||||||
execve(CRASHREPORT, (char * const *)xargv, environ);
|
execve(CRASHREPORT, (char * const *)xargv, environ);
|
||||||
char err[100];
|
char err[100];
|
||||||
sprintf(err, "Can't start " CRASHREPORT ": %s", strerror(errno));
|
sprintf(err, "Can't start " CRASHREPORT ": %s", strerror(errno));
|
||||||
@@ -401,36 +582,45 @@ submit_web_report(const char *msg, char *why){
|
|||||||
} else {
|
} else {
|
||||||
int status;
|
int status;
|
||||||
errno=0;
|
errno=0;
|
||||||
// XXX do we _really_ know this is the right pid?
|
|
||||||
(void)waitpid(pid, &status, 0);
|
(void)waitpid(pid, &status, 0);
|
||||||
if (status) { // XXX check could be more precise
|
if (status) { // XXX check could be more precise
|
||||||
#if 0
|
#ifdef BETA
|
||||||
// Not useful at the moment. XXX
|
// Not useful at the moment. XXX
|
||||||
char err[100];
|
char err[100];
|
||||||
sprintf(err, "pid=%d e=%d status=%0x",wpid,errno,status);
|
sprintf(err, "pid=%d e=%d status=%0x",pid,errno,status);
|
||||||
raw_print(err);
|
raw_print(err);
|
||||||
#endif
|
#endif
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* free(info); -- Don't risk it. */
|
/* free(info); -- Don't risk it. */
|
||||||
|
#endif
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
dobugreport(void){
|
||||||
|
if(!submit_web_report(2, NULL, "#bugreport command")){
|
||||||
|
pline("Unable to send bug report. Please visit %s instead.",
|
||||||
|
sysopt.crashreporturl
|
||||||
|
? sysopt.crashreporturl
|
||||||
|
: "https://www.nethack.org"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return ECMD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* CRASHREPORT */
|
#endif /* CRASHREPORT */
|
||||||
#undef SWR_ADD
|
#undef SWR_ADD
|
||||||
|
#undef SWR_ADD_URIcoded
|
||||||
#undef SWR_FRAMES
|
#undef SWR_FRAMES
|
||||||
#undef SWR_HDR
|
#undef SWR_HDR
|
||||||
#undef SWR_LINES
|
#undef SWR_LINES
|
||||||
|
|
||||||
/*ARGSUSED*/
|
/*ARGSUSED*/
|
||||||
static boolean
|
static boolean
|
||||||
NH_panictrace_libc(char *why UNUSED)
|
NH_panictrace_libc(void)
|
||||||
{
|
{
|
||||||
#ifdef CRASHREPORT
|
|
||||||
if(submit_web_report("Panic",why)) return TRUE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef PANICTRACE_LIBC
|
#ifdef PANICTRACE_LIBC
|
||||||
void *bt[20];
|
void *bt[20];
|
||||||
@@ -459,13 +649,13 @@ NH_panictrace_libc(char *why UNUSED)
|
|||||||
* fooVAR (possibly const) variable containing fooPATH
|
* fooVAR (possibly const) variable containing fooPATH
|
||||||
*/
|
*/
|
||||||
#ifdef PANICTRACE_GDB
|
#ifdef PANICTRACE_GDB
|
||||||
#ifdef SYSCF
|
# ifdef SYSCF
|
||||||
#define GDBVAR sysopt.gdbpath
|
# define GDBVAR sysopt.gdbpath
|
||||||
#define GREPVAR sysopt.greppath
|
# define GREPVAR sysopt.greppath
|
||||||
#else /* SYSCF */
|
# else /* SYSCF */
|
||||||
#define GDBVAR GDBPATH
|
# define GDBVAR GDBPATH
|
||||||
#define GREPVAR GREPPATH
|
# define GREPVAR GREPPATH
|
||||||
#endif /* SYSCF */
|
# endif /* SYSCF */
|
||||||
#endif /* PANICTRACE_GDB */
|
#endif /* PANICTRACE_GDB */
|
||||||
|
|
||||||
static boolean
|
static boolean
|
||||||
@@ -878,7 +1068,7 @@ panic VA_DECL(const char *, str)
|
|||||||
? "."
|
? "."
|
||||||
: "\nand it may be possible to rebuild.";
|
: "\nand it may be possible to rebuild.";
|
||||||
|
|
||||||
// XXX this is probably wrong if defined(CRASHREPORT)
|
// XXX this may need an update if defined(CRASHREPORT) TBD
|
||||||
if (sysopt.support)
|
if (sysopt.support)
|
||||||
raw_printf("To report this error, %s%s", sysopt.support,
|
raw_printf("To report this error, %s%s", sysopt.support,
|
||||||
maybe_rebuild);
|
maybe_rebuild);
|
||||||
@@ -984,6 +1174,27 @@ dump_plines(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// lineno==0 gives the most recent message (e.g. "Do you want to call panic..."
|
||||||
|
// if called from #panic)
|
||||||
|
static const char *
|
||||||
|
get_saved_pline(int lineno){
|
||||||
|
int p;
|
||||||
|
int limit = DUMPLOG_MSG_COUNT;
|
||||||
|
if(lineno >= DUMPLOG_MSG_COUNT) return NULL;
|
||||||
|
p = (gs.saved_pline_index-1) % DUMPLOG_MSG_COUNT;
|
||||||
|
|
||||||
|
while(limit--){
|
||||||
|
if(gs.saved_plines[p]){ // valid line
|
||||||
|
if(lineno--){
|
||||||
|
p = (p-1+DUMPLOG_MSG_COUNT) % DUMPLOG_MSG_COUNT;
|
||||||
|
} else {
|
||||||
|
return gs.saved_plines[p];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*ARGSUSED*/
|
/*ARGSUSED*/
|
||||||
|
|||||||
@@ -4736,6 +4736,9 @@ reveal_paths(void)
|
|||||||
#endif /* ?UNIX */
|
#endif /* ?UNIX */
|
||||||
|
|
||||||
raw_print("");
|
raw_print("");
|
||||||
|
#if defined(WIN32) && !defined(WIN32CON)
|
||||||
|
wait_synch();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------- BEGIN TRIBUTE ----------- */
|
/* ---------- BEGIN TRIBUTE ----------- */
|
||||||
|
|||||||
@@ -678,6 +678,12 @@ static const char *const build_opts[] = {
|
|||||||
#endif
|
#endif
|
||||||
#ifdef SYSCF
|
#ifdef SYSCF
|
||||||
"system configuration at run-time",
|
"system configuration at run-time",
|
||||||
|
#endif
|
||||||
|
#ifdef PANICTRACE
|
||||||
|
"show stack trace on error",
|
||||||
|
#endif
|
||||||
|
#ifdef CRASHREPORT
|
||||||
|
"launch browser to report issues",
|
||||||
#endif
|
#endif
|
||||||
save_bones_compat_buf,
|
save_bones_compat_buf,
|
||||||
"and basic NetHack features"
|
"and basic NetHack features"
|
||||||
|
|||||||
@@ -522,7 +522,7 @@ parseoptions(
|
|||||||
* determine_ambiguities()
|
* determine_ambiguities()
|
||||||
* figured out exactly how many characters are required to
|
* figured out exactly how many characters are required to
|
||||||
* unambiguously differentiate one option from all others, and it
|
* unambiguously differentiate one option from all others, and it
|
||||||
* placed that number into each option's alloption[n].minmatch.
|
* placed that number into each option's allopt[n].minmatch.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
if (!got_match)
|
if (!got_match)
|
||||||
@@ -1205,6 +1205,80 @@ optfn_catname(
|
|||||||
return optn_ok;
|
return optn_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
optfn_crash_email(int optidx UNUSED, int req, boolean negated UNUSED, char *opts, char *op)
|
||||||
|
{
|
||||||
|
if (req == do_init) {
|
||||||
|
return optn_ok;
|
||||||
|
}
|
||||||
|
if (req == do_set) {
|
||||||
|
if ((op = string_for_opt(opts, FALSE))
|
||||||
|
!= empty_optstr) {
|
||||||
|
gc.crash_email = dupstr(op);
|
||||||
|
} else
|
||||||
|
return optn_err;
|
||||||
|
return optn_ok;
|
||||||
|
}
|
||||||
|
if (req == get_val || req == get_cnf_val) {
|
||||||
|
if (!opts)
|
||||||
|
return optn_err;
|
||||||
|
Sprintf(opts, "%s", gc.crash_email);
|
||||||
|
return optn_ok;
|
||||||
|
}
|
||||||
|
return optn_ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
optfn_crash_name(int optidx UNUSED, int req, boolean negated UNUSED, char *opts, char *op)
|
||||||
|
{
|
||||||
|
if (req == do_init) {
|
||||||
|
return optn_ok;
|
||||||
|
}
|
||||||
|
if (req == do_set) {
|
||||||
|
if ((op = string_for_opt(opts, FALSE))
|
||||||
|
!= empty_optstr) {
|
||||||
|
gc.crash_name = dupstr(op);
|
||||||
|
} else
|
||||||
|
return optn_err;
|
||||||
|
return optn_ok;
|
||||||
|
}
|
||||||
|
if (req == get_val || req == get_cnf_val) {
|
||||||
|
if (!opts)
|
||||||
|
return optn_err;
|
||||||
|
Sprintf(opts, "%s", gc.crash_name);
|
||||||
|
return optn_ok;
|
||||||
|
}
|
||||||
|
return optn_ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
optfn_crash_urlmax(int optidx UNUSED, int req, boolean negated UNUSED, char *opts, char *op)
|
||||||
|
{
|
||||||
|
if (req == do_init) {
|
||||||
|
return optn_ok;
|
||||||
|
}
|
||||||
|
if (req == do_set) {
|
||||||
|
if ((op = string_for_opt(opts, FALSE))
|
||||||
|
!= empty_optstr) {
|
||||||
|
int temp = atoi(op);
|
||||||
|
if(temp < 75){
|
||||||
|
config_error_add("Invalid value %d for crash_urlmax. Minimum value is 75.",temp);
|
||||||
|
return optn_err;
|
||||||
|
}
|
||||||
|
gc.crash_urlmax = temp;
|
||||||
|
} else
|
||||||
|
return optn_err;
|
||||||
|
return optn_ok;
|
||||||
|
}
|
||||||
|
if (req == get_val || req == get_cnf_val) {
|
||||||
|
if (!opts)
|
||||||
|
return optn_err;
|
||||||
|
Sprintf(opts, "%d", gc.crash_urlmax);
|
||||||
|
return optn_ok;
|
||||||
|
}
|
||||||
|
return optn_ok;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CURSES_GRAPHICS
|
#ifdef CURSES_GRAPHICS
|
||||||
static int
|
static int
|
||||||
optfn_cursesgraphics(int optidx, int req, boolean negated,
|
optfn_cursesgraphics(int optidx, int req, boolean negated,
|
||||||
@@ -6694,8 +6768,6 @@ initoptions(void)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
go.opt_phase = builtin_opt;
|
|
||||||
initoptions_init();
|
|
||||||
/*
|
/*
|
||||||
* Call each option function with an init flag and give it a chance
|
* Call each option function with an init flag and give it a chance
|
||||||
* to make any preparations that it might require. We do this
|
* to make any preparations that it might require. We do this
|
||||||
@@ -6740,6 +6812,7 @@ initoptions_init(void)
|
|||||||
#endif
|
#endif
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
go.opt_phase = builtin_opt; // Did I need to move this here?
|
||||||
memcpy(allopt, allopt_init, sizeof(allopt));
|
memcpy(allopt, allopt_init, sizeof(allopt));
|
||||||
determine_ambiguities();
|
determine_ambiguities();
|
||||||
|
|
||||||
|
|||||||
@@ -537,7 +537,7 @@ impossible(const char *s, ...)
|
|||||||
boolean report = ('y' == yn_function("Report now?","yn",'n',FALSE));
|
boolean report = ('y' == yn_function("Report now?","yn",'n',FALSE));
|
||||||
raw_print(""); // prove to the user the character was accepted
|
raw_print(""); // prove to the user the character was accepted
|
||||||
if(report){
|
if(report){
|
||||||
submit_web_report("Impossible", pbuf);
|
submit_web_report(1,"Impossible", pbuf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ LUA2NHTOP = ../../..
|
|||||||
LUABASELIB = liblua-$(LUA_VERSION).a
|
LUABASELIB = liblua-$(LUA_VERSION).a
|
||||||
TOPLUALIB = lib/lua/$(LUABASELIB)
|
TOPLUALIB = lib/lua/$(LUABASELIB)
|
||||||
|
|
||||||
ALLDEP = $(GAME) recover Guidebook $(VARDAT) spec_levs check-dlb check-nhlua
|
ALLDEP = $(GAME) recover Guidebook $(VARDAT) spec_levs check-dlb
|
||||||
|
|
||||||
# first target is also the default target for 'make' without any arguments
|
# first target is also the default target for 'make' without any arguments
|
||||||
all: $(ALLDEP)
|
all: $(ALLDEP)
|
||||||
@@ -148,10 +148,6 @@ luabin:
|
|||||||
( cd $(LUATOP) \
|
( cd $(LUATOP) \
|
||||||
&& make $(LUAMAKEFILES) all && cd $(LUA2NHTOP) )
|
&& make $(LUAMAKEFILES) all && cd $(LUA2NHTOP) )
|
||||||
|
|
||||||
check-nhlua:
|
|
||||||
( util/makedefs --grep-defined CRASHREPORT && ( \
|
|
||||||
cd $(LUATOP) && make $(LUAMAKEFLAGS) ); true )
|
|
||||||
|
|
||||||
# hints file could set LUATESTTARGET to this if GITSUBMODULES is defined
|
# hints file could set LUATESTTARGET to this if GITSUBMODULES is defined
|
||||||
submodules/lua/lua.h:
|
submodules/lua/lua.h:
|
||||||
git submodule init submodules/lua
|
git submodule init submodules/lua
|
||||||
|
|||||||
@@ -291,11 +291,7 @@ VARDIR = $(HACKDIR)
|
|||||||
POSTINSTALL+= cp -n sys/unix/sysconf $(INSTDIR)/sysconf; \
|
POSTINSTALL+= cp -n sys/unix/sysconf $(INSTDIR)/sysconf; \
|
||||||
$(CHOWN) $(GAMEUID) $(INSTDIR)/sysconf; \
|
$(CHOWN) $(GAMEUID) $(INSTDIR)/sysconf; \
|
||||||
$(CHGRP) $(GAMEGRP) $(INSTDIR)/sysconf; \
|
$(CHGRP) $(GAMEGRP) $(INSTDIR)/sysconf; \
|
||||||
chmod $(VARFILEPERM) $(INSTDIR)/sysconf; \
|
chmod $(VARFILEPERM) $(INSTDIR)/sysconf;
|
||||||
( util/makedefs --grep-defined CRASHREPORT && \
|
|
||||||
( cp win/share/nhcrashreport.lua $(INSTDIR) ; \
|
|
||||||
chmod 555 $(INSTDIR)/nhcrashreport.lua ; \
|
|
||||||
cp $(LUATOP)/lua $(INSTDIR)/nhlua); true)
|
|
||||||
|
|
||||||
ifneq "$(CCISCLANG)" ""
|
ifneq "$(CCISCLANG)" ""
|
||||||
# gdb may not be installed if clang is chosen compiler so the game
|
# gdb may not be installed if clang is chosen compiler so the game
|
||||||
|
|||||||
@@ -31,6 +31,8 @@ ifndef LIBXPM
|
|||||||
LIBXPM= -L/opt/X11/lib -lXpm
|
LIBXPM= -L/opt/X11/lib -lXpm
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
#WANT_WIN_CHAIN=1
|
||||||
|
|
||||||
# 4. Other
|
# 4. Other
|
||||||
|
|
||||||
#-----------------------------------------------------------------------------
|
#-----------------------------------------------------------------------------
|
||||||
@@ -98,7 +100,7 @@ NHCFLAGS+=-DNOMAIL
|
|||||||
#NHCFLAGS+=-DNO_CHRONICLE
|
#NHCFLAGS+=-DNO_CHRONICLE
|
||||||
#NHCFLAGS+=-DLIVELOG
|
#NHCFLAGS+=-DLIVELOG
|
||||||
# not NHCFLAGS - needed for makedefs
|
# not NHCFLAGS - needed for makedefs
|
||||||
CFLAGS+=-DCRASHREPORT=\"NetHackCrashReport.JavaScript\"
|
CFLAGS+=-DCRASHREPORT=\"/usr/bin/open\"
|
||||||
|
|
||||||
ifdef MAKEFILE_SRC
|
ifdef MAKEFILE_SRC
|
||||||
# default
|
# default
|
||||||
@@ -334,10 +336,7 @@ PREINSTALL= . sys/unix/hints/macosx.sh user2 $(GAMEUID); \
|
|||||||
POSTINSTALL+= sys/unix/hints/macosx.sh editsysconf sys/unix/sysconf $(HACKDIR)/sysconf; \
|
POSTINSTALL+= sys/unix/hints/macosx.sh editsysconf sys/unix/sysconf $(HACKDIR)/sysconf; \
|
||||||
$(CHOWN) $(GAMEUID) $(HACKDIR)/sysconf; \
|
$(CHOWN) $(GAMEUID) $(HACKDIR)/sysconf; \
|
||||||
$(CHGRP) $(GAMEGRP) $(HACKDIR)/sysconf; \
|
$(CHGRP) $(GAMEGRP) $(HACKDIR)/sysconf; \
|
||||||
chmod $(VARFILEPERM) $(HACKDIR)/sysconf; \
|
chmod $(VARFILEPERM) $(HACKDIR)/sysconf;
|
||||||
util/makedefs --grep-defined CRASHREPORT && \
|
|
||||||
( cp win/macosx/NetHackCrashReport.JavaScript $(HACKDIR) && \
|
|
||||||
chmod 0500 $(HACKDIR)/NetHackCrashReport.JavaScript )
|
|
||||||
|
|
||||||
else ifdef WANT_SOURCE_INSTALL
|
else ifdef WANT_SOURCE_INSTALL
|
||||||
|
|
||||||
@@ -353,10 +352,7 @@ CHGRP=/usr/bin/true
|
|||||||
GAMEPERM = 0700
|
GAMEPERM = 0700
|
||||||
VARFILEPERM = 0600
|
VARFILEPERM = 0600
|
||||||
VARDIRPERM = 0700
|
VARDIRPERM = 0700
|
||||||
POSTINSTALL+= sys/unix/hints/macosx.sh editsysconf sys/unix/sysconf $(HACKDIR)/sysconf; \
|
POSTINSTALL+= sys/unix/hints/macosx.sh editsysconf sys/unix/sysconf $(HACKDIR)/sysconf;
|
||||||
util/makedefs --grep-defined CRASHREPORT && \
|
|
||||||
( cp win/macosx/NetHackCrashReport.JavaScript $(HACKDIR) && \
|
|
||||||
chmod 0500 $(HACKDIR)/NetHackCrashReport.JavaScript )
|
|
||||||
|
|
||||||
# We can use "make all" to build the whole thing - but it misses some things:
|
# We can use "make all" to build the whole thing - but it misses some things:
|
||||||
MOREALL=$(MAKE) install
|
MOREALL=$(MAKE) install
|
||||||
@@ -385,10 +381,7 @@ PREINSTALL+= (mkdir $(SHELLDIR) || true);
|
|||||||
POSTINSTALL+= sys/unix/hints/macosx.sh editsysconf sys/unix/sysconf $(HACKDIR)/sysconf; \
|
POSTINSTALL+= sys/unix/hints/macosx.sh editsysconf sys/unix/sysconf $(HACKDIR)/sysconf; \
|
||||||
$(CHOWN) $(GAMEUID) $(HACKDIR)/sysconf; \
|
$(CHOWN) $(GAMEUID) $(HACKDIR)/sysconf; \
|
||||||
$(CHGRP) $(GAMEGRP) $(HACKDIR)/sysconf; \
|
$(CHGRP) $(GAMEGRP) $(HACKDIR)/sysconf; \
|
||||||
chmod $(VARFILEPERM) $(HACKDIR)/sysconf; \
|
chmod $(VARFILEPERM) $(HACKDIR)/sysconf;
|
||||||
util/makedefs --grep-defined CRASHREPORT && \
|
|
||||||
( cp win/macosx/NetHackCrashReport.JavaScript $(HACKDIR) && \
|
|
||||||
chmod 0500 $(HACKDIR)/NetHackCrashReport.JavaScript )
|
|
||||||
|
|
||||||
endif # !WANT_SHARE_INSTALL
|
endif # !WANT_SHARE_INSTALL
|
||||||
|
|
||||||
@@ -731,7 +724,6 @@ build_package_root:
|
|||||||
install -p doc/recover.6 $(PKGROOT_UG)/man/man6
|
install -p doc/recover.6 $(PKGROOT_UG)/man/man6
|
||||||
install -p doc/Guidebook $(PKGROOT_UG)/doc
|
install -p doc/Guidebook $(PKGROOT_UG)/doc
|
||||||
install -p dat/nhdat $(PKGROOT_UGLN)
|
install -p dat/nhdat $(PKGROOT_UGLN)
|
||||||
#XXX no code to package NetHackCrashReport.JavaScript
|
|
||||||
sys/unix/hints/macosx.sh editsysconf sys/unix/sysconf $(PKGROOT_UGLN)/sysconf
|
sys/unix/hints/macosx.sh editsysconf sys/unix/sysconf $(PKGROOT_UGLN)/sysconf
|
||||||
cd dat; install -p $(DATNODLB) ../$(PKGROOT_UGLN)
|
cd dat; install -p $(DATNODLB) ../$(PKGROOT_UGLN)
|
||||||
# XXX these files should be somewhere else for good Mac form
|
# XXX these files should be somewhere else for good Mac form
|
||||||
|
|||||||
@@ -159,6 +159,9 @@ GREPPATH=/bin/grep
|
|||||||
PANICTRACE_GDB=1
|
PANICTRACE_GDB=1
|
||||||
PANICTRACE_LIBC=2
|
PANICTRACE_LIBC=2
|
||||||
|
|
||||||
|
# URL loaded for creating reports to the NetHack DevTeam
|
||||||
|
#CRASHREPORTURL=https://nethack.org/links/cr-37BETA.html
|
||||||
|
|
||||||
# 'portable_device_paths' is only supported for Windows. Starting with
|
# 'portable_device_paths' is only supported for Windows. Starting with
|
||||||
# 3.6.3, nethack on Windows treats the folder containing nethack.exe and
|
# 3.6.3, nethack on Windows treats the folder containing nethack.exe and
|
||||||
# nethackW.exe as read-only and puts data files which are generated or
|
# nethackW.exe as read-only and puts data files which are generated or
|
||||||
|
|||||||
@@ -151,6 +151,7 @@ main(int argc, char *argv[])
|
|||||||
check_linux_console();
|
check_linux_console();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
initoptions_init();
|
||||||
initoptions();
|
initoptions();
|
||||||
#ifdef PANICTRACE
|
#ifdef PANICTRACE
|
||||||
ARGV0 = gh.hname; /* save for possible stack trace */
|
ARGV0 = gh.hname; /* save for possible stack trace */
|
||||||
@@ -766,6 +767,7 @@ opt_showpaths(const char *dir)
|
|||||||
nhUse(dir);
|
nhUse(dir);
|
||||||
#endif
|
#endif
|
||||||
iflags.initoptions_noterminate = TRUE;
|
iflags.initoptions_noterminate = TRUE;
|
||||||
|
initoptions_init();
|
||||||
initoptions();
|
initoptions();
|
||||||
iflags.initoptions_noterminate = FALSE;
|
iflags.initoptions_noterminate = FALSE;
|
||||||
reveal_paths();
|
reveal_paths();
|
||||||
|
|||||||
@@ -233,3 +233,7 @@ OPTIONS=hilite_status:gold/up/yellow/down/brown
|
|||||||
# St, Dx, Co, In, Wi, Ch
|
# St, Dx, Co, In, Wi, Ch
|
||||||
OPTIONS=hilite_status:characteristics/up/green/down/red
|
OPTIONS=hilite_status:characteristics/up/green/down/red
|
||||||
|
|
||||||
|
# CRASHREPORTURL must be set in syscf to enable these options.
|
||||||
|
# These identify you in crash reports
|
||||||
|
#OPTIONS=crash_name:Your Name
|
||||||
|
#OPTIONS=crash_email:user@example.com
|
||||||
|
|||||||
@@ -52,9 +52,10 @@ SOUND_LIBRARIES = windsound
|
|||||||
#
|
#
|
||||||
#---------------------------------------------------------------
|
#---------------------------------------------------------------
|
||||||
# Do you want debug information in the executable?
|
# Do you want debug information in the executable?
|
||||||
|
# Required for CRASHREPORT.
|
||||||
#
|
#
|
||||||
|
|
||||||
DEBUGINFO = N
|
DEBUGINFO = Y
|
||||||
|
|
||||||
#
|
#
|
||||||
#---------------------------------------------------------------
|
#---------------------------------------------------------------
|
||||||
@@ -243,6 +244,7 @@ NHV=$(subst ",,$(NHV1))
|
|||||||
# TTY - window port files (tty)
|
# TTY - window port files (tty)
|
||||||
# MSWIN - window port files (win32)
|
# MSWIN - window port files (win32)
|
||||||
# WCURSES - window port files (curses)
|
# WCURSES - window port files (curses)
|
||||||
|
# WCHAIN - window port files (chain)
|
||||||
# WSHR - Tile support files
|
# WSHR - Tile support files
|
||||||
# SNDSYS - sound suppport files for win32
|
# SNDSYS - sound suppport files for win32
|
||||||
# QT - QT window support files
|
# QT - QT window support files
|
||||||
@@ -257,6 +259,7 @@ SNDSYS =../sound/windsound
|
|||||||
MSWSYS =../sys/windows
|
MSWSYS =../sys/windows
|
||||||
TTY =../win/tty
|
TTY =../win/tty
|
||||||
MSWIN =../win/win32
|
MSWIN =../win/win32
|
||||||
|
WCHAIN =../win/chain
|
||||||
WCURSES =../win/curses
|
WCURSES =../win/curses
|
||||||
WSHR =../win/share
|
WSHR =../win/share
|
||||||
QT =../win/Qt
|
QT =../win/Qt
|
||||||
@@ -357,7 +360,7 @@ $(OBJ):
|
|||||||
|
|
||||||
CLEAN_DIR = $(GAMEDIR) $(OBJ)
|
CLEAN_DIR = $(GAMEDIR) $(OBJ)
|
||||||
|
|
||||||
#===============-=================================================
|
#=================================================================
|
||||||
# LUA library
|
# LUA library
|
||||||
# Source from http://www.lua.org/ftp/lua-5.4.6.tar.gz
|
# Source from http://www.lua.org/ftp/lua-5.4.6.tar.gz
|
||||||
#=================================================================
|
#=================================================================
|
||||||
@@ -987,6 +990,15 @@ CFLAGSW += $(NHCURSESFLAGS)
|
|||||||
NHWONLY += $(addsuffix .o, cursdial cursinit cursinvt cursmain cursmesg cursmisc cursstat curswins guitty)
|
NHWONLY += $(addsuffix .o, cursdial cursinit cursinvt cursmain cursmesg cursmisc cursstat curswins guitty)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# uncomment for WINCHAIN
|
||||||
|
#COREOBJS += $(addsuffix .o, wc_chainin wc_chainout wc_trace)
|
||||||
|
|
||||||
|
# XXX mess for testing libbacktrace
|
||||||
|
ifeq "$(DEBUGINFO)" "Y"
|
||||||
|
CFLAGS += -I/mingw64/include -g -static -gdwarf
|
||||||
|
LIBS += -L/mingw64/lib -lbacktrace
|
||||||
|
endif
|
||||||
|
|
||||||
nethackw: $(NHWTARGETS)
|
nethackw: $(NHWTARGETS)
|
||||||
|
|
||||||
$(GAMEDIR)/NetHackW.exe: $(NHWOBJS) $(NHWRES) $(DATEW_O) $(LUALIB) $(PDCWLIB) | $(GAMEDIR)
|
$(GAMEDIR)/NetHackW.exe: $(NHWOBJS) $(NHWRES) $(DATEW_O) $(LUALIB) $(PDCWLIB) | $(GAMEDIR)
|
||||||
@@ -1028,6 +1040,9 @@ $(ONHW)/%.o: $(MSWSYS)/%.c $(NHLUAH) | $(ONHW)
|
|||||||
$(ONHW)/%.o: $(MSWIN)/%.c $(NHLUAH) | $(ONHW)
|
$(ONHW)/%.o: $(MSWIN)/%.c $(NHLUAH) | $(ONHW)
|
||||||
$(cc) $(CFLAGSW) $< -o$@
|
$(cc) $(CFLAGSW) $< -o$@
|
||||||
|
|
||||||
|
$(ONHW)/%.o: $(WCHAIN)/%.c $(NHLUAH) | $(ONHW)
|
||||||
|
$(cc) $(CFLAGSW) $< -o$@
|
||||||
|
|
||||||
$(ONHW)/%.o: $(WSHR)/%.c $(NHLUAH) | $(ONHW)
|
$(ONHW)/%.o: $(WSHR)/%.c $(NHLUAH) | $(ONHW)
|
||||||
$(cc) $(CFLAGSW) $< -o$@
|
$(cc) $(CFLAGSW) $< -o$@
|
||||||
|
|
||||||
@@ -1068,6 +1083,7 @@ NHCURSESFLAGS = -DCURSES_GRAPHICS -DCURSES_UNICODE $(PDCURSESFLAGS) -DPDC_NCMOUS
|
|||||||
CFLAGSNH += $(NHCURSESFLAGS)
|
CFLAGSNH += $(NHCURSESFLAGS)
|
||||||
NHONLY += $(addsuffix .o, cursdial cursinit cursinvt cursmain cursmesg cursmisc cursstat curswins)
|
NHONLY += $(addsuffix .o, cursdial cursinit cursinvt cursmain cursmesg cursmisc cursstat curswins)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
DATE_O = $(addsuffix .o, $(addprefix $(ONH)/, date))
|
DATE_O = $(addsuffix .o, $(addprefix $(ONH)/, date))
|
||||||
|
|
||||||
NHOBJS = $(addprefix $(ONH)/, $(COREOBJS) $(NHONLY))
|
NHOBJS = $(addprefix $(ONH)/, $(COREOBJS) $(NHONLY))
|
||||||
@@ -1115,6 +1131,9 @@ $(ONH)/%.o: $(MSWSYS)/%.c $(NHLUAH) | $(ONH)
|
|||||||
$(ONH)/%.o: $(MSWIN)/%.c $(NHLUAH) | $(ONH)
|
$(ONH)/%.o: $(MSWIN)/%.c $(NHLUAH) | $(ONH)
|
||||||
$(cc) $(CFLAGSNH) $< -o$@
|
$(cc) $(CFLAGSNH) $< -o$@
|
||||||
|
|
||||||
|
$(ONH)/%.o: $(WCHAIN)/%.c $(NHLUAH) | $(ONH)
|
||||||
|
$(cc) $(CFLAGSNH) $< -o$@
|
||||||
|
|
||||||
$(ONH)/%.o: $(WSHR)/%.c $(NHLUAH) | $(ONH)
|
$(ONH)/%.o: $(WSHR)/%.c $(NHLUAH) | $(ONH)
|
||||||
$(cc) $(CFLAGSNH) $< -o$@
|
$(cc) $(CFLAGSNH) $< -o$@
|
||||||
|
|
||||||
@@ -1148,8 +1167,9 @@ CLEAN_FILE += $(NHTARGET) $(NHOBJS) $(NHRES)
|
|||||||
all: install
|
all: install
|
||||||
|
|
||||||
TO_INSTALL = $(GAMEDIR)/NetHack.exe $(RTARGETS) $(GAMEDIRDLLS) \
|
TO_INSTALL = $(GAMEDIR)/NetHack.exe $(RTARGETS) $(GAMEDIRDLLS) \
|
||||||
$(addprefix $(GAMEDIR)/, $(addsuffix .template, sysconf .nethackrc) \
|
$(addprefix $(GAMEDIR)/, \
|
||||||
Guidebook.txt NetHack.txt license opthelp record symbols)
|
$(addsuffix .template, sysconf .nethackrc symbols) \
|
||||||
|
Guidebook.txt NetHack.txt license opthelp record)
|
||||||
|
|
||||||
ifeq "$(HAVE_SOUNDLIB)" "Y"
|
ifeq "$(HAVE_SOUNDLIB)" "Y"
|
||||||
TO_INSTALL += $(addprefix $(GAMEDIR)/, $(addsuffix .wav, $(WAVLIST)))
|
TO_INSTALL += $(addprefix $(GAMEDIR)/, $(addsuffix .wav, $(WAVLIST)))
|
||||||
@@ -1183,7 +1203,7 @@ $(GAMEDIR)/$(FMODLIBDLL): $(FMODLIBDIR)/$(FMODLIBDLL)
|
|||||||
cp $< $@
|
cp $< $@
|
||||||
endif
|
endif
|
||||||
|
|
||||||
$(GAMEDIR)/symbols: $(DAT)/symbols
|
$(GAMEDIR)/symbols.template: $(DAT)/symbols
|
||||||
cp $< $@
|
cp $< $@
|
||||||
|
|
||||||
$(GAMEDIR)/NetHack.txt: $(DOC)/nethack.txt
|
$(GAMEDIR)/NetHack.txt: $(DOC)/nethack.txt
|
||||||
|
|||||||
@@ -121,3 +121,6 @@ HIDEUSAGE=1
|
|||||||
#
|
#
|
||||||
# The location that file synchronization locks are stored (writeable)
|
# The location that file synchronization locks are stored (writeable)
|
||||||
#LOCKDIR=c:\ProgramData\NetHack\3.7
|
#LOCKDIR=c:\ProgramData\NetHack\3.7
|
||||||
|
|
||||||
|
# URL loaded for creating reports to the NetHack DevTeam
|
||||||
|
#CRASHREPORTURL=https://nethack.org/links/cr-37BETA.html
|
||||||
|
|||||||
@@ -49,7 +49,7 @@
|
|||||||
<PreprocessorDefinitions>WIN32CON;NO_TILE_C;DLB;SAFEPROCS;SND_LIB_WINDSOUND;USER_SOUNDS;_LIB;HAS_STDINT_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32CON;NO_TILE_C;DLB;SAFEPROCS;SND_LIB_WINDSOUND;USER_SOUNDS;_LIB;HAS_STDINT_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;winmm.lib;Winmm.lib;bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>kernel32.lib;dbghelp.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;winmm.lib;Winmm.lib;bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
</Link>
|
</Link>
|
||||||
<ResourceCompile>
|
<ResourceCompile>
|
||||||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SndWavDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SndWavDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
@@ -297,4 +297,4 @@
|
|||||||
<Target Name="AfterRebuild">
|
<Target Name="AfterRebuild">
|
||||||
<MSBuild Projects="afternethack.proj" Targets="Build" Properties="Configuration=$(Configuration)" />
|
<MSBuild Projects="afternethack.proj" Targets="Build" Properties="Configuration=$(Configuration)" />
|
||||||
</Target>
|
</Target>
|
||||||
</Project>
|
</Project>
|
||||||
@@ -62,7 +62,7 @@
|
|||||||
</ResourceCompile>
|
</ResourceCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Windows</SubSystem>
|
<SubSystem>Windows</SubSystem>
|
||||||
<AdditionalDependencies>comctl32.lib;winmm.lib;bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>dbghelp.lib;comctl32.lib;winmm.lib;bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
</Link>
|
</Link>
|
||||||
<Manifest>
|
<Manifest>
|
||||||
<AdditionalManifestFiles>$(WinWin32Dir)NethackW.exe.manifest;%(AdditionalManifestFiles)</AdditionalManifestFiles>
|
<AdditionalManifestFiles>$(WinWin32Dir)NethackW.exe.manifest;%(AdditionalManifestFiles)</AdditionalManifestFiles>
|
||||||
@@ -351,4 +351,4 @@
|
|||||||
<Target Name="AfterRebuild">
|
<Target Name="AfterRebuild">
|
||||||
<MSBuild Projects="$(vsDir)NetHack\afternethack.proj" Targets="Build" Properties="Configuration=$(Configuration)" />
|
<MSBuild Projects="$(vsDir)NetHack\afternethack.proj" Targets="Build" Properties="Configuration=$(Configuration)" />
|
||||||
</Target>
|
</Target>
|
||||||
</Project>
|
</Project>
|
||||||
@@ -545,7 +545,7 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/
|
|||||||
if (getcwd(orgdir, sizeof orgdir) == (char *) 0)
|
if (getcwd(orgdir, sizeof orgdir) == (char *) 0)
|
||||||
error("NetHack: current directory path too long");
|
error("NetHack: current directory path too long");
|
||||||
#endif
|
#endif
|
||||||
|
initoptions_init(); // This allows OPTIONS in syscf on Windows.
|
||||||
set_default_prefix_locations(argv[0]);
|
set_default_prefix_locations(argv[0]);
|
||||||
|
|
||||||
#if defined(CHDIR) && !defined(NOCWD_ASSUMPTIONS)
|
#if defined(CHDIR) && !defined(NOCWD_ASSUMPTIONS)
|
||||||
@@ -638,6 +638,9 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/
|
|||||||
if (WINDOWPORT(tty))
|
if (WINDOWPORT(tty))
|
||||||
consoletty_open(1);
|
consoletty_open(1);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef WINCHAIN
|
||||||
|
commit_windowchain();
|
||||||
|
#endif
|
||||||
|
|
||||||
init_nhwindows(&argc, argv);
|
init_nhwindows(&argc, argv);
|
||||||
|
|
||||||
@@ -812,6 +815,11 @@ process_options(int argc, char * argv[])
|
|||||||
argc--;
|
argc--;
|
||||||
argv++;
|
argv++;
|
||||||
}
|
}
|
||||||
|
#if defined(CRASHREPORT)
|
||||||
|
if (argcheck(argc, argv, ARG_BIDSHOW) == 2) {
|
||||||
|
nethack_exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (argc > 1 && !strncmp(argv[1], "-d", 2) && argv[1][2] != 'e') {
|
if (argc > 1 && !strncmp(argv[1], "-d", 2) && argv[1][2] != 'e') {
|
||||||
/* avoid matching "-dec" for DECgraphics; since the man page
|
/* avoid matching "-dec" for DECgraphics; since the man page
|
||||||
* says -d directory, hope nobody's using -desomething_else
|
* says -d directory, hope nobody's using -desomething_else
|
||||||
|
|||||||
@@ -24,7 +24,10 @@
|
|||||||
#ifdef TTY_GRAPHICS
|
#ifdef TTY_GRAPHICS
|
||||||
#include "wintty.h"
|
#include "wintty.h"
|
||||||
#endif
|
#endif
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
|
#include <VersionHelpers.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The following WIN32 API routines are used in this file.
|
* The following WIN32 API routines are used in this file.
|
||||||
@@ -758,6 +761,281 @@ nt_assert_failed(const char *expression, const char *filepath, int line)
|
|||||||
expression, filename, line);
|
expression, filename, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Windows helpers for CRASHREPORT etc */
|
||||||
|
#ifdef CRASHREPORT
|
||||||
|
struct CRctxt {
|
||||||
|
BCRYPT_ALG_HANDLE bah;
|
||||||
|
BCRYPT_HASH_HANDLE bhh;
|
||||||
|
PBYTE pbhashobj;
|
||||||
|
DWORD cbhashobj; /* temp */
|
||||||
|
DWORD cbhash; /* hash length */
|
||||||
|
DWORD cbdata; /* temp */
|
||||||
|
PBYTE pbhash; /* binary hash */
|
||||||
|
NTSTATUS st;
|
||||||
|
} ctxp_ = { NULL, NULL, NULL, 0, 0, 0, NULL, 0 };
|
||||||
|
struct CRctxt *ctxp = &ctxp_; // XXX should this now be in gc.* ?
|
||||||
|
|
||||||
|
#define win32err(fn) errname = fn; goto error
|
||||||
|
|
||||||
|
int
|
||||||
|
win32_cr_helper(char cmd, struct CRctxt *ctxp, void *p, int d){
|
||||||
|
char *errname = "unknown";
|
||||||
|
switch (cmd) {
|
||||||
|
default:
|
||||||
|
/* Not panic - we don't want to upgrade an impossible to a
|
||||||
|
* panic due to a bug in the CRASHREPORT code. */
|
||||||
|
impossible("win_cr_helper bad cmd %d", cmd);
|
||||||
|
return 1;
|
||||||
|
case 'D': {
|
||||||
|
char *bidstr = (char *) p;
|
||||||
|
wchar_t lbidstr[40]; // sizeof(bid), but const
|
||||||
|
swprintf_s(lbidstr, 40, L"%S", bidstr);
|
||||||
|
// XXX TODO: need something that will allow copy of just the bid
|
||||||
|
return MessageBoxW(NULL, lbidstr, L"bidshow", MB_SETFOREGROUND);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'i': /* HASH_INIT(ctxp) */
|
||||||
|
if (!IsWindowsVistaOrGreater())
|
||||||
|
return 1; // CNG not available.
|
||||||
|
ctxp->bah = NULL;
|
||||||
|
ctxp->bhh = NULL;
|
||||||
|
ctxp->pbhashobj = NULL;
|
||||||
|
ctxp->cbhashobj = 0;
|
||||||
|
ctxp->cbhash = 0;
|
||||||
|
ctxp->cbdata = 0;
|
||||||
|
ctxp->pbhash = NULL;
|
||||||
|
ctxp->st = 0;
|
||||||
|
// win32err("test"); // TESTING - FAKE AN ERROR
|
||||||
|
if (0 > (ctxp->st = BCryptOpenAlgorithmProvider(
|
||||||
|
&ctxp->bah, BCRYPT_MD4_ALGORITHM, NULL, 0))) {
|
||||||
|
win32err("BCryptOpenAlgorithmProvider");
|
||||||
|
};
|
||||||
|
if (0 > (ctxp->st =
|
||||||
|
BCryptGetProperty(ctxp->bah, BCRYPT_OBJECT_LENGTH,
|
||||||
|
(unsigned char *) &ctxp->cbhashobj,
|
||||||
|
sizeof(DWORD), &ctxp->cbdata, 0))) {
|
||||||
|
win32err("BCryptGetProperty1");
|
||||||
|
};
|
||||||
|
if (0
|
||||||
|
== (ctxp->pbhashobj =
|
||||||
|
HeapAlloc(GetProcessHeap(), 0, ctxp->cbhashobj))) {
|
||||||
|
win32err("HeapAlloc1");
|
||||||
|
};
|
||||||
|
if (0 > (ctxp->st = BCryptGetProperty(
|
||||||
|
ctxp->bah, BCRYPT_HASH_LENGTH, (PBYTE) &ctxp->cbhash,
|
||||||
|
sizeof(DWORD), &ctxp->cbdata, 0))) {
|
||||||
|
win32err("BCryptGetProperty2");
|
||||||
|
}
|
||||||
|
if (0
|
||||||
|
== (ctxp->pbhash =
|
||||||
|
HeapAlloc(GetProcessHeap(), 0, ctxp->cbhash))) {
|
||||||
|
|
||||||
|
win32err("HeapAlloc2\n");
|
||||||
|
}
|
||||||
|
if (0 > BCryptCreateHash(ctxp->bah, &ctxp->bhh, ctxp->pbhashobj,
|
||||||
|
ctxp->cbhashobj, NULL, 0, 0)) {
|
||||||
|
win32err("BCryptCreateHash");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'u': /* HASH_UPDATE(ctxp, ptr, len) */
|
||||||
|
if (0 > (ctxp->st = BCryptHashData(ctxp->bhh, p, d, 0))) {
|
||||||
|
win32err("BCryptHashData");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'f': /* HASH_FINISH(ctxp) */
|
||||||
|
if (0 > BCryptFinishHash(ctxp->bhh, ctxp->pbhash, ctxp->cbhash, 0)) {
|
||||||
|
win32err("BCryptFinishHash");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'c': /* HASH_CLEANUP(ctxp) */
|
||||||
|
if (ctxp->bah) {
|
||||||
|
BCryptCloseAlgorithmProvider(ctxp->bah, 0);
|
||||||
|
}
|
||||||
|
if (ctxp->bhh) {
|
||||||
|
BCryptDestroyHash(ctxp->bhh);
|
||||||
|
}
|
||||||
|
if (ctxp->pbhashobj) {
|
||||||
|
HeapFree(GetProcessHeap(), 0, ctxp->pbhashobj);
|
||||||
|
}
|
||||||
|
if (ctxp->pbhash) {
|
||||||
|
HeapFree(GetProcessHeap(), 0, ctxp->pbhash);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 's': /* HASH_RESULT_SIZE(ctxp) */
|
||||||
|
return ctxp->cbhash;
|
||||||
|
case 'r': /* HASH_RESULT(ctxp, resp) */
|
||||||
|
*(unsigned char **)p = ctxp->pbhash;
|
||||||
|
break;
|
||||||
|
case 'b': /* HASH_BINFILE(NULL,&binfile,0) */
|
||||||
|
// XXX This buffer should be allocated, not static (and freed in
|
||||||
|
// HASH_CLEANUP).
|
||||||
|
// NB: assumes !longPathAware in manifest (Win10+)
|
||||||
|
{
|
||||||
|
static char binfile[MAX_PATH];
|
||||||
|
DWORD rv = GetModuleFileNameA(NULL, binfile, sizeof(binfile));
|
||||||
|
if (rv == 0 || rv == sizeof(binfile))
|
||||||
|
return 1;
|
||||||
|
#ifdef BETA
|
||||||
|
printf("FILE '%s'\n", binfile);
|
||||||
|
#endif
|
||||||
|
*(unsigned char **) p = (unsigned char *) binfile;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0; /* ok */
|
||||||
|
error:
|
||||||
|
raw_printf("WIN32 function %s failed: status=%" PRIx64 "\n",
|
||||||
|
errname, (uint64)ctxp->st);
|
||||||
|
return 1; /* fail */
|
||||||
|
}
|
||||||
|
#undef win32err
|
||||||
|
|
||||||
|
|
||||||
|
#include <shellapi.h>
|
||||||
|
#define MAX_SYM_SIZE 100
|
||||||
|
#ifdef __GNUC__
|
||||||
|
// gcc can't generate .pdb files. llvm can almost do it.
|
||||||
|
// For these platforms, use github/ianlancetaylor/libbacktrace.
|
||||||
|
// XXX this doesn't work yet - we get correct addresses but no symbol info
|
||||||
|
// XXX so still needs cleanup
|
||||||
|
// XXX no mark (overflow held to last valid segment) handling yet
|
||||||
|
#include <backtrace.h>
|
||||||
|
|
||||||
|
struct userstate {
|
||||||
|
int error_count;
|
||||||
|
int good_count;
|
||||||
|
char *out;
|
||||||
|
int outsize;
|
||||||
|
int maxframes;
|
||||||
|
} userstate;
|
||||||
|
|
||||||
|
//backtrace_full_callback
|
||||||
|
static int
|
||||||
|
btfcb_fn(void *us0, uintptr_t pc, const char *filename,
|
||||||
|
int lineno, const char *fnname){
|
||||||
|
struct userstate *us = us0;
|
||||||
|
//XXX generate a stack frame line
|
||||||
|
printf("C: pc=%llx f=%s line=%d fn=%s\n",pc,filename,lineno,fnname);
|
||||||
|
us->good_count++;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//backtrace_error_callback
|
||||||
|
static void
|
||||||
|
btecb_fn(void *us0, const char *msg, int errnum){
|
||||||
|
struct userstate *us = us0;
|
||||||
|
us->error_count++;
|
||||||
|
if(errnum < 0){
|
||||||
|
printf("E1: M=%s e=%d\n",msg,errnum);
|
||||||
|
// XXX save error message
|
||||||
|
} else {
|
||||||
|
printf("E2: M=%s e=%d\n",msg,errnum);
|
||||||
|
// errnum is an errno
|
||||||
|
//XXX save error message with strerror
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
win32_cr_gettrace(int maxframes, char *out, int outsize){
|
||||||
|
userstate.error_count = 0;
|
||||||
|
userstate.good_count = 0;
|
||||||
|
userstate.out = out;
|
||||||
|
userstate.outsize = outsize;
|
||||||
|
userstate.maxframes = maxframes;
|
||||||
|
static char binfile[MAX_PATH];// assumes !longPathAware in manifest (Win10+)
|
||||||
|
DWORD rv = GetModuleFileNameA(NULL, binfile, sizeof(binfile));
|
||||||
|
struct backtrace_state *state
|
||||||
|
= backtrace_create_state(binfile, 0, btecb_fn, &userstate);
|
||||||
|
if(!state) return userstate.error_count + userstate.good_count;
|
||||||
|
rv=backtrace_full(state, 0, btfcb_fn, btecb_fn, &userstate);
|
||||||
|
printf("rv=%d\n",rv);
|
||||||
|
// XXX rv not checked
|
||||||
|
// XXX this API leaks its memory; there is no free function
|
||||||
|
return userstate.error_count + userstate.good_count;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
// Use win32 API with Visual Studio (and probably MSVC).
|
||||||
|
#include <dbghelp.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
win32_cr_gettrace(int maxframes, char *out, int outsize){
|
||||||
|
char *mark = out;
|
||||||
|
void *frames[200]; // XXX why does VS fail var array? wrong C std?
|
||||||
|
int x;
|
||||||
|
int tmp;
|
||||||
|
#define BSIZE (MAX_SYM_SIZE+50)
|
||||||
|
char buf[BSIZE];
|
||||||
|
HANDLE me = GetCurrentProcess();
|
||||||
|
SetLastError(0);
|
||||||
|
// XXX may need to pass the binary's dir
|
||||||
|
//XXX check for different flags
|
||||||
|
if(!SymInitialize(me, NULL, TRUE)){
|
||||||
|
snprintf(buf, BSIZE, "no stack trace: SymInitialize: %d\n",
|
||||||
|
GetLastError());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
int fcount = CaptureStackBackTrace(0, maxframes,frames,NULL);
|
||||||
|
if(!fcount)goto finish;
|
||||||
|
char symbol_info_space[sizeof(SYMBOL_INFO)+MAX_SYM_SIZE];
|
||||||
|
SYMBOL_INFO *si = (SYMBOL_INFO *)symbol_info_space;
|
||||||
|
si->MaxNameLen = MAX_SYM_SIZE;
|
||||||
|
si->SizeOfStruct = sizeof(SYMBOL_INFO);
|
||||||
|
|
||||||
|
for(x=0;x<fcount;x++){
|
||||||
|
DWORD64 disp64 =0 ;
|
||||||
|
DWORD64 adr = (DWORD64)(frames[x]);
|
||||||
|
if(!adr) break;
|
||||||
|
if(SymFromAddr(me, adr, &disp64, si)){
|
||||||
|
//printf("A %x\n",GetLastError());fflush(stdout);
|
||||||
|
tmp = snprintf(buf, BSIZE, "%d %p %s+%lld\n",
|
||||||
|
x, frames[x], &si->Name[0], (long long int)disp64);
|
||||||
|
if(swr_add_uricoded(buf, &out, &outsize, mark))
|
||||||
|
goto finish;
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
// XXX does this block do anything useful?
|
||||||
|
DWORD disp = (DWORD) disp64;
|
||||||
|
IMAGEHLP_LINE ihl;
|
||||||
|
ihl.SizeOfStruct = sizeof(IMAGEHLP_LINE);
|
||||||
|
if (SymGetLineFromAddr(me, adr, &disp, &ihl)) {
|
||||||
|
printf("L=%d\n", ihl.LineNumber);
|
||||||
|
} else {
|
||||||
|
// 7e/1e7 - no info. May need to call SymLoadModule if we need those addrs
|
||||||
|
// BUT probably system code, so we don't care - experiment
|
||||||
|
// printf("SGLFA failed: $%08x\n", GetLastError());
|
||||||
|
}
|
||||||
|
//XXXnow format the line
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
// Error 487 (invalid address) seems to mean
|
||||||
|
// "I can't find any info for this address".
|
||||||
|
tmp = snprintf(buf, BSIZE, "%d %p (error %d)\n",
|
||||||
|
x, frames[x], GetLastError());
|
||||||
|
if(swr_add_uricoded(buf, &out, &outsize, mark))
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
if(tmp < 0 || tmp >= outsize){ // XXX is test now wrong?
|
||||||
|
//printf("FAIL tmp=%d\n",tmp);
|
||||||
|
fcount = x+1;
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
mark = out;
|
||||||
|
}
|
||||||
|
finish:
|
||||||
|
SymCleanup(me);
|
||||||
|
return fcount; // XXX if output truncated, fcount could be wrong
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int *
|
||||||
|
win32_cr_shellexecute(const char *url){
|
||||||
|
//XXX Docs say to do this, but has so many caveats I'm going to try skipping it.
|
||||||
|
//CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
|
||||||
|
int *rv = (int*)ShellExecuteA(NULL, "open", url, NULL, NULL, SW_SHOWNORMAL);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
#endif /* CRASHREPORT */
|
||||||
|
|
||||||
#endif /* WIN32 */
|
#endif /* WIN32 */
|
||||||
|
|
||||||
/*windsys.c*/
|
/*windsys.c*/
|
||||||
|
|||||||
@@ -84,3 +84,8 @@ OPTIONS=catname:Ghisteslwchlohm
|
|||||||
# 048 035 064 042 \
|
# 048 035 064 042 \
|
||||||
# 047 045 092 124 124 092 045 047 \
|
# 047 045 092 124 124 092 045 047 \
|
||||||
# 047 064 092 064 064 064 092 064 047
|
# 047 064 092 064 064 064 092 064 047
|
||||||
|
|
||||||
|
# CRASHREPORTURL must be set in syscf to enable these options.
|
||||||
|
# These identify you in crash reports
|
||||||
|
#OPTIONS=crash_name:Your Name
|
||||||
|
#OPTIONS=crash_email:user@example.com
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ chainin_procs_chain(
|
|||||||
tdp->nprocs = 0;
|
tdp->nprocs = 0;
|
||||||
tdp->ndata = 0;
|
tdp->ndata = 0;
|
||||||
tdp->linknum = n;
|
tdp->linknum = n;
|
||||||
cibase = 0;
|
cibase = tdp;
|
||||||
break;
|
break;
|
||||||
case WINCHAIN_INIT:
|
case WINCHAIN_INIT:
|
||||||
tdp = me;
|
tdp = me;
|
||||||
@@ -584,7 +584,7 @@ chainin_ctrl_nhwindow(
|
|||||||
int request,
|
int request,
|
||||||
win_request_info *wri)
|
win_request_info *wri)
|
||||||
{
|
{
|
||||||
boolean rv;
|
win_request_info *rv;
|
||||||
|
|
||||||
rv = (*cibase->nprocs->win_ctrl_nhwindow)(cibase->ndata, window,
|
rv = (*cibase->nprocs->win_ctrl_nhwindow)(cibase->ndata, window,
|
||||||
request, wri);
|
request, wri);
|
||||||
@@ -609,7 +609,7 @@ struct window_procs chainin_procs = {
|
|||||||
chainin_display_nhwindow, chainin_destroy_nhwindow, chainin_curs,
|
chainin_display_nhwindow, chainin_destroy_nhwindow, chainin_curs,
|
||||||
chainin_putstr, chainin_putmixed, chainin_display_file,
|
chainin_putstr, chainin_putmixed, chainin_display_file,
|
||||||
chainin_start_menu, chainin_add_menu, chainin_end_menu,
|
chainin_start_menu, chainin_add_menu, chainin_end_menu,
|
||||||
chainin_select_menu, chainin_message_menu, chainin_update_inventory,
|
chainin_select_menu, chainin_message_menu,
|
||||||
chainin_mark_synch, chainin_wait_synch,
|
chainin_mark_synch, chainin_wait_synch,
|
||||||
#ifdef CLIPPING
|
#ifdef CLIPPING
|
||||||
chainin_cliparound,
|
chainin_cliparound,
|
||||||
|
|||||||
@@ -702,12 +702,13 @@ chainout_can_suspend(void *vp)
|
|||||||
|
|
||||||
win_request_info *
|
win_request_info *
|
||||||
chainout_ctrl_nhwindow(
|
chainout_ctrl_nhwindow(
|
||||||
|
void *vp,
|
||||||
winid window,
|
winid window,
|
||||||
int request,
|
int request,
|
||||||
win_request_info *wri)
|
win_request_info *wri)
|
||||||
{
|
{
|
||||||
struct chainout_data *tdp = vp;
|
struct chainout_data *tdp = vp;
|
||||||
boolean rv;
|
win_request_info *rv;
|
||||||
|
|
||||||
rv = (*tdp->nprocs->win_ctrl_nhwindow)(window,
|
rv = (*tdp->nprocs->win_ctrl_nhwindow)(window,
|
||||||
request, wri);
|
request, wri);
|
||||||
@@ -733,7 +734,8 @@ struct chain_procs chainout_procs = {
|
|||||||
chainout_destroy_nhwindow, chainout_curs, chainout_putstr,
|
chainout_destroy_nhwindow, chainout_curs, chainout_putstr,
|
||||||
chainout_putmixed, chainout_display_file, chainout_start_menu,
|
chainout_putmixed, chainout_display_file, chainout_start_menu,
|
||||||
chainout_add_menu, chainout_end_menu, chainout_select_menu,
|
chainout_add_menu, chainout_end_menu, chainout_select_menu,
|
||||||
chainout_message_menu, chainout_update_inventory, chainout_mark_synch,
|
chainout_message_menu,
|
||||||
|
chainout_mark_synch,
|
||||||
chainout_wait_synch,
|
chainout_wait_synch,
|
||||||
#ifdef CLIPPING
|
#ifdef CLIPPING
|
||||||
chainout_cliparound,
|
chainout_cliparound,
|
||||||
|
|||||||
@@ -9,8 +9,15 @@
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
FILE *wc_tracelogf; /* Should be static, but it's just too useful to have
|
#ifdef WIN32
|
||||||
* access to this logfile from arbitrary other files. */
|
long getpid(void);
|
||||||
|
long
|
||||||
|
getpid(){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
FILE *wc_tracelogf;
|
||||||
static unsigned int indent_level; /* Some winfuncs call other winfuncs, so
|
static unsigned int indent_level; /* Some winfuncs call other winfuncs, so
|
||||||
* we need to support nesting. */
|
* we need to support nesting. */
|
||||||
|
|
||||||
@@ -55,7 +62,6 @@ void trace_add_menu(void *,winid, const glyph_info *, const ANY_P *,
|
|||||||
void trace_end_menu(void *,winid, const char *);
|
void trace_end_menu(void *,winid, const char *);
|
||||||
int trace_select_menu(void *,winid, int, MENU_ITEM_P **);
|
int trace_select_menu(void *,winid, int, MENU_ITEM_P **);
|
||||||
char trace_message_menu(void *,char, int, const char *);
|
char trace_message_menu(void *,char, int, const char *);
|
||||||
void trace_update_inventory(void *,int);
|
|
||||||
void trace_mark_synch(void *);
|
void trace_mark_synch(void *);
|
||||||
void trace_wait_synch(void *);
|
void trace_wait_synch(void *);
|
||||||
#ifdef CLIPPING
|
#ifdef CLIPPING
|
||||||
@@ -101,6 +107,8 @@ void trace_status_update(void *,int, genericptr_t, int, int, int,
|
|||||||
unsigned long *);
|
unsigned long *);
|
||||||
|
|
||||||
boolean trace_can_suspend(void *);
|
boolean trace_can_suspend(void *);
|
||||||
|
void trace_update_inventory(void *,int);
|
||||||
|
win_request_info *trace_ctrl_nhwindow(void *, winid, int, win_request_info *);
|
||||||
|
|
||||||
void trace_procs_init(int dir);
|
void trace_procs_init(int dir);
|
||||||
void *trace_procs_chain(int cmd, int n, void *me, void *nextprocs, void *nextdata);
|
void *trace_procs_chain(int cmd, int n, void *me, void *nextprocs, void *nextdata);
|
||||||
@@ -144,7 +152,7 @@ trace_procs_chain(
|
|||||||
void
|
void
|
||||||
trace_procs_init(int dir)
|
trace_procs_init(int dir)
|
||||||
{
|
{
|
||||||
char fname[200];
|
char tfile[20];
|
||||||
long pid;
|
long pid;
|
||||||
|
|
||||||
/* processors shouldn't need this test, but just in case */
|
/* processors shouldn't need this test, but just in case */
|
||||||
@@ -152,8 +160,14 @@ trace_procs_init(int dir)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
pid = (long) getpid();
|
pid = (long) getpid();
|
||||||
Sprintf(fname, "%s/tlog.%ld", HACKDIR, pid);
|
|
||||||
|
Sprintf(tfile, "tlog.%ld", pid);
|
||||||
|
// XXX FQN_NUMBUF is private to files.c
|
||||||
|
const char *fname = fqname(tfile, TROUBLEPREFIX,7);
|
||||||
|
printf("TRACEFILE: %s\n",fname);
|
||||||
|
fflush(stdout);
|
||||||
wc_tracelogf = fopen(fname, "w");
|
wc_tracelogf = fopen(fname, "w");
|
||||||
|
(void)setvbuf(wc_tracelogf, NULL, _IONBF, 0);
|
||||||
if (!wc_tracelogf) {
|
if (!wc_tracelogf) {
|
||||||
fprintf(stderr, "Can't open trace log file %s: %s\n", fname,
|
fprintf(stderr, "Can't open trace log file %s: %s\n", fname,
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
@@ -578,6 +592,16 @@ trace_update_inventory(void *vp, int arg)
|
|||||||
POST;
|
POST;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
win_request_info *
|
||||||
|
trace_ctrl_nhwindow(void *vp, winid w, int request, win_request_info *wri){
|
||||||
|
struct trace_data *tdp = vp;
|
||||||
|
|
||||||
|
fprintf(wc_tracelogf, "%sctrl_nhwindow(%d, %d, %p)\n", INDENT, w, request, wri);
|
||||||
|
PRE;
|
||||||
|
(*tdp->nprocs->win_ctrl_nhwindow)(tdp->ndata, w, request, wri);
|
||||||
|
POST;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
trace_mark_synch(void *vp)
|
trace_mark_synch(void *vp)
|
||||||
{
|
{
|
||||||
@@ -1186,7 +1210,8 @@ trace_can_suspend(void *vp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct chain_procs trace_procs = {
|
struct chain_procs trace_procs = {
|
||||||
"+trace", 0, /* wincap */
|
"+trace", wp_trace,
|
||||||
|
0, /* wincap */
|
||||||
0, /* wincap2 */
|
0, /* wincap2 */
|
||||||
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* color availability */
|
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* color availability */
|
||||||
/*
|
/*
|
||||||
@@ -1202,7 +1227,7 @@ struct chain_procs trace_procs = {
|
|||||||
trace_create_nhwindow, trace_clear_nhwindow, trace_display_nhwindow,
|
trace_create_nhwindow, trace_clear_nhwindow, trace_display_nhwindow,
|
||||||
trace_destroy_nhwindow, trace_curs, trace_putstr, trace_putmixed,
|
trace_destroy_nhwindow, trace_curs, trace_putstr, trace_putmixed,
|
||||||
trace_display_file, trace_start_menu, trace_add_menu, trace_end_menu,
|
trace_display_file, trace_start_menu, trace_add_menu, trace_end_menu,
|
||||||
trace_select_menu, trace_message_menu, trace_update_inventory,
|
trace_select_menu, trace_message_menu,
|
||||||
trace_mark_synch, trace_wait_synch,
|
trace_mark_synch, trace_wait_synch,
|
||||||
#ifdef CLIPPING
|
#ifdef CLIPPING
|
||||||
trace_cliparound,
|
trace_cliparound,
|
||||||
@@ -1228,4 +1253,6 @@ struct chain_procs trace_procs = {
|
|||||||
trace_status_init, trace_status_finish, trace_status_enablefield,
|
trace_status_init, trace_status_finish, trace_status_enablefield,
|
||||||
trace_status_update,
|
trace_status_update,
|
||||||
trace_can_suspend,
|
trace_can_suspend,
|
||||||
|
trace_update_inventory,
|
||||||
|
trace_ctrl_nhwindow
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,28 +0,0 @@
|
|||||||
#!/usr/bin/osascript -l JavaScript
|
|
||||||
|
|
||||||
// NetHack 3.7 tile.h $NHDT-Date: 1693083762 2023/08/26 21:02:42 $ $NHDT-Branch: keni-crashweb2 $:$NHDT-Revision: 1.1 $
|
|
||||||
// Copyright (c) 2023 Kenneth Lorber
|
|
||||||
// NetHack may be freely redistributed. See license for details.
|
|
||||||
|
|
||||||
// Call with URL then field value pairs. Opens a new browser window
|
|
||||||
// to: URL?field=value+field=value.....
|
|
||||||
// This program encodes the values; fieldnames don't require encoding.
|
|
||||||
|
|
||||||
// Should be installed in the playground.
|
|
||||||
|
|
||||||
function run(argv){
|
|
||||||
|
|
||||||
var url = argv[0];
|
|
||||||
var argcp = 1;
|
|
||||||
|
|
||||||
url += "?cos=1"; // Start the query string and set mode
|
|
||||||
while(argcp < argv.length){
|
|
||||||
url += "&" + argv[argcp] + "=" + encodeURIComponent(argv[argcp+1])
|
|
||||||
argcp += 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
var safari = Application('Safari');
|
|
||||||
var nw = safari.make({ new:"document" });
|
|
||||||
nw.url = url;
|
|
||||||
safari.activate();
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
#!./nhlua
|
|
||||||
-- NetHack 3.7 nhcrashreport.lua $NHDT-Date: 1693083824 2023/08/26 21:03:44 $ $NHDT-Branch: keni-crashweb2 $:$NHDT-Revision: 1.0 $
|
|
||||||
-- Copyright (c) 2023 Kenneth Lorber
|
|
||||||
-- NetHack may be freely redistributed. See license for details.
|
|
||||||
|
|
||||||
-- Call with URL then field value pairs. Opens a new browser window
|
|
||||||
-- to: URL?field=value+field=value.....
|
|
||||||
-- This program encodes the values; fieldnames don't require encoding.
|
|
||||||
--
|
|
||||||
-- Should be installed in the playground.
|
|
||||||
|
|
||||||
----
|
|
||||||
-- from
|
|
||||||
-- https://github.com/daurnimator/lua-http/blob/master/http/util.lua
|
|
||||||
-- Encodes a character as a percent encoded string
|
|
||||||
local function char_to_pchar(c)
|
|
||||||
return string.format("%%%02X", c:byte(1,1))
|
|
||||||
end
|
|
||||||
-- encodeURIComponent escapes all characters except the following: alphabetic, decimal digits, - _ . ! ~ * ' ( )
|
|
||||||
local function encodeURIComponent(str)
|
|
||||||
return (str:gsub("[^%w%-_%.%!%~%*%'%(%)]", char_to_pchar))
|
|
||||||
end
|
|
||||||
----
|
|
||||||
|
|
||||||
function un20(str)
|
|
||||||
return str:gsub("%%20","+")
|
|
||||||
end
|
|
||||||
|
|
||||||
url = table.remove(arg,1) .. "?cos=1"; -- Start the query string and set mode
|
|
||||||
while #arg > 0 do
|
|
||||||
local field = table.remove(arg,1)
|
|
||||||
local value = table.remove(arg,1)
|
|
||||||
url = url .. "&" .. field .. "=" .. un20(encodeURIComponent(value))
|
|
||||||
end
|
|
||||||
--print("url='"..url.."'")
|
|
||||||
cmd = '/usr/bin/xdg-open "'..url..'"'
|
|
||||||
os.execute(cmd)
|
|
||||||
os.exit()
|
|
||||||
Reference in New Issue
Block a user