From 65655d2ceefa2eb7099b05c5034d72044b9b1176 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 28 Jan 2018 22:54:08 -0500 Subject: [PATCH 1/4] Incorporate some git information into NetHack Incorporate some git information into NetHack so that it is potentially visible to a player. That's useful when collecting details about the version that they are running and, if the gitinfo is present, it can tie the code to a specific git commit in the repository. This modifies 'makedefs -v' to check for the presence of a data file called dat/gitinfo.txt and if it is there, parse out its contents, then write additional lines to include/date.h beyond what 'makedefs -v' was previously putting in there, similar to this sample: #define NETHACK_GIT_SHA "0c84e564c78e2024e562d39539376ce2e21eec8e" #define NETHACK_GIT_BRANCH "NetHack-3.6.0" The contents of an appropriate dat/gitinfo.txt are as follows, and trailing/leading whitespace is not significant: githash = 0c84e564c78e2024e562d39539376ce2e21eec8e gitbranch = NetHack-3.6.0 It also adjusts the contents of the 'v' version information to include the additional git info when available. Also adds some hooks DEVEL/hooksdir and a perl file to DEVEL for simplifying and automating the deposit of dat/gitinfo.txt so that it generally reflects the most current git commit. DEVEL/gitinfo.pl can be used to build dat/gitinfo.txt at any time without doing a commit, merge, or checkout. perl DEVEL/gitinfo.pl command line --version and -version support To complement the extra information being provided in the version by the 'v' command, this also adds support for the following new command line arguments: --version -version Output the NetHack version string then exit. --version:paste Output the NetHack version string and also copy it to -version:paste the platform's paste buffer for insertion somewhere, then exit. If the paste variation of -version is requested on a platform that hasn't incorporated any support for the capability, it will deliver the version info then an error message, prior to exiting. To support the extended -version:paste variation, a port needs to: - provide a port-specific routine to perform the paste buffer copy in a port code file. - #define RUNTIME_PASTEBUF_SUPPORT in the include/portconf.h header file. --skeleton-- void port_insert_pastebuf(buf) char *buf; { /* insert code to copy the version info from buf into platform's paste buffer in a supported way */ } macosx and Windows have both added support for RUNTIME_PASTEBUF_SUPPORT --- DEVEL/gitinfo.pl | 26 ++++++++ DEVEL/hooksdir/NHgithook.pm | 30 +++++++++ DEVEL/hooksdir/post-checkout | 1 + DEVEL/hooksdir/post-commit | 1 + DEVEL/hooksdir/post-merge | 2 + doc/makedefs.6 | 8 +++ doc/nethack.6 | 14 +++++ include/decl.h | 9 +++ include/extern.h | 5 ++ include/ntconf.h | 11 ++-- include/unixconf.h | 4 ++ src/allmain.c | 82 +++++++++++++++++++++++++ src/version.c | 57 +++++++++++++++-- sys/share/pcmain.c | 3 + sys/unix/unixmain.c | 39 ++++++++++++ sys/winnt/winnt.c | 116 +++++++++++++++++++++++++++++++++++ util/makedefs.c | 86 ++++++++++++++++++++++++++ 17 files changed, 485 insertions(+), 9 deletions(-) create mode 100644 DEVEL/gitinfo.pl diff --git a/DEVEL/gitinfo.pl b/DEVEL/gitinfo.pl new file mode 100644 index 000000000..b62428975 --- /dev/null +++ b/DEVEL/gitinfo.pl @@ -0,0 +1,26 @@ +#!/usr/bin/perl + +#STARTUP-START +BEGIN { + # OS hackery has to be duplicated in each of the hooks :/ + # first the directory separator + my $DS = quotemeta('/'); + my $PDS = '/'; + # msys: POSIXish over a Windows filesystem (so / not \ but \r\n not \n). + # temporarily removed because inconsistent behavior + # if ($^O eq "msys") + # { + # $/ = "\r\n"; + # $\ = "\r\n"; + # } + if($^O eq "MSWin32"){ + $DS = quotemeta('\\'); + $PDS = '\\'; + } + $gitdir = `git rev-parse --git-dir`; + chomp $gitdir; + push(@INC, $gitdir.$PDS."hooks"); +} +use NHgithook; + +&NHgithook::nhversioning; diff --git a/DEVEL/hooksdir/NHgithook.pm b/DEVEL/hooksdir/NHgithook.pm index 6024c1c03..1bb92cf7e 100644 --- a/DEVEL/hooksdir/NHgithook.pm +++ b/DEVEL/hooksdir/NHgithook.pm @@ -60,6 +60,36 @@ sub POST { &do_hook("POST"); } +### +### store githash and gitbranch in dat/gitinfo.txt +### + +sub nhversioning { + use strict; + use warnings; + + my $git_sha = `git rev-parse HEAD`; + $git_sha =~ s/\s+//g; + my $git_branch = `git rev-parse --abbrev-ref HEAD`; + $git_branch =~ s/\s+//g; + + if (open my $fh, '<', 'dat/gitinfo.txt') { + while(my $line = <$fh>) { + if ((index $line, $git_sha) >= 0) { + close $fh; + print "No update made to dat/gitinfo.txt, existing githash=".$git_sha."\n"; + return; + } + } + close $fh; + } + if (open my $fh, '>', 'dat/gitinfo.txt') { + print $fh 'githash='.$git_sha."\n"; + print $fh 'gitbranch='.$git_branch."\n"; + print "An updated dat/gitinfo.txt was written, githash=".$git_sha."\n"; + } +} + # PRIVATE sub do_hook { my($p) = @_; diff --git a/DEVEL/hooksdir/post-checkout b/DEVEL/hooksdir/post-checkout index b5bf990fe..2df107a2f 100755 --- a/DEVEL/hooksdir/post-checkout +++ b/DEVEL/hooksdir/post-checkout @@ -26,5 +26,6 @@ use NHgithook; #STARTUP-END &NHgithook::PRE; +&NHgithook::nhversioning; &NHgithook::POST; exit 0; diff --git a/DEVEL/hooksdir/post-commit b/DEVEL/hooksdir/post-commit index b5bf990fe..2df107a2f 100755 --- a/DEVEL/hooksdir/post-commit +++ b/DEVEL/hooksdir/post-commit @@ -26,5 +26,6 @@ use NHgithook; #STARTUP-END &NHgithook::PRE; +&NHgithook::nhversioning; &NHgithook::POST; exit 0; diff --git a/DEVEL/hooksdir/post-merge b/DEVEL/hooksdir/post-merge index b5bf990fe..2dc7f3628 100755 --- a/DEVEL/hooksdir/post-merge +++ b/DEVEL/hooksdir/post-merge @@ -22,9 +22,11 @@ BEGIN { chomp $gitdir; push(@INC, $gitdir.$PDS."hooks"); } + use NHgithook; #STARTUP-END &NHgithook::PRE; +&NHgithook::nhversioning; &NHgithook::POST; exit 0; diff --git a/doc/makedefs.6 b/doc/makedefs.6 index 7b55de3e4..29d4899be 100644 --- a/doc/makedefs.6 +++ b/doc/makedefs.6 @@ -85,6 +85,14 @@ Generate .I date.h and .I options +file. It will read +.I dat/gitinfo.txt +,only if it is present, to obtain +.B githash= +and +.B gitbranch= + info and include related preprocessor #defines in +.I date.h file. .br .TP diff --git a/doc/nethack.6 b/doc/nethack.6 index 3803ae583..6b38a68ba 100644 --- a/doc/nethack.6 +++ b/doc/nethack.6 @@ -55,6 +55,9 @@ nethack \- Exploring The Mazes of Menace [ .I playernames ] +[ +.B \-\-version +] .ad .hy 14 .\" Make sure path is not hyphenated below @@ -207,6 +210,17 @@ The playground must contain several auxiliary files such as help files, the list of top scorers, and a subdirectory .I save where games are saved. +.PP +.B \-\-version +can be used to cause NetHack to show the version information it +was compiled with, then exit. That will include the +.I git +commit hash if the information was available when the game was compiled. +On some platforms, such as windows and macosx, a variation +.B \-\-version:paste +can be used to cause NetHack to show the version information, then exit, +while also leaving a copy of the version information in the paste buffer +or clipboard for potential insertion into things like bug reports. .SH AUTHORS .PP Jay Fenlason (+ Kenny Woodland, Mike Thome and Jon Payne) wrote the diff --git a/include/decl.h b/include/decl.h index f6d5764cb..bf99227f9 100644 --- a/include/decl.h +++ b/include/decl.h @@ -422,6 +422,15 @@ E struct plinemsg_type *plinemsg_types; E const char *ARGV0; #endif +enum earlyarg {ARG_DEBUG, ARG_VERSION}; + +struct early_opt { + enum earlyarg e; + const char *name; + int minlength; + boolean valallowed; +}; + #undef E #endif /* DECL_H */ diff --git a/include/extern.h b/include/extern.h index 24a0c06cd..4ea4915c4 100644 --- a/include/extern.h +++ b/include/extern.h @@ -26,6 +26,7 @@ E void NDECL(display_gamewindows); E void NDECL(newgame); E void FDECL(welcome, (BOOLEAN_P)); E time_t NDECL(get_realtime); +E boolean FDECL(argcheck, (int, char **, enum earlyarg)); /* ### apply.c ### */ @@ -2567,10 +2568,14 @@ E void FDECL(store_version, (int)); E unsigned long FDECL(get_feature_notice_ver, (char *)); E unsigned long NDECL(get_current_feature_ver); E const char *FDECL(copyright_banner_line, (int)); +E void FDECL(early_version_info, (BOOLEAN_P)); #ifdef RUNTIME_PORT_ID E char *FDECL(get_port_id, (char *)); #endif +#ifdef RUNTIME_PASTEBUF_SUPPORT +E void FDECL(port_insert_pastebuf, (char *)); +#endif /* ### video.c ### */ diff --git a/include/ntconf.h b/include/ntconf.h index a096a2ff1..534fa6e5d 100644 --- a/include/ntconf.h +++ b/include/ntconf.h @@ -69,6 +69,12 @@ #define PORT_DEBUG /* include ability to debug international keyboard issues \ */ +#define RUNTIME_PORT_ID /* trigger run-time port identification for \ + * identification of exe CPU architecture \ + */ +#define RUNTIME_PASTEBUF_SUPPORT + + #define SAFERHANGUP /* Define SAFERHANGUP to delay hangup processing \ * until the main command loop. 'safer' because it \ * avoids certain cheats and also avoids losing \ @@ -117,11 +123,6 @@ extern void FDECL(interject, (int)); #endif #endif /* _MSC_VER */ - -#define RUNTIME_PORT_ID /* trigger run-time port identification for \ - * identification of exe CPU architecture \ - */ - /* The following is needed for prototypes of certain functions */ #if defined(_MSC_VER) #include /* Provides prototypes of exit(), spawn() */ diff --git a/include/unixconf.h b/include/unixconf.h index 0d4fbce17..88e309d55 100644 --- a/include/unixconf.h +++ b/include/unixconf.h @@ -387,5 +387,9 @@ #endif /* LINUX */ #endif /* GNOME_GRAPHICS */ +#ifdef __APPLE__ +# define RUNTIME_PASTEBUF_SUPPORT +#endif + #endif /* UNIXCONF_H */ #endif /* UNIX */ diff --git a/src/allmain.c b/src/allmain.c index 4a0cfaf8f..789c5d48f 100644 --- a/src/allmain.c +++ b/src/allmain.c @@ -737,5 +737,87 @@ const char *msg; } } +/* + * Argument processing helpers - for xxmain() to share + * and call. + * + * These should return TRUE if the argument matched, + * whether the processing of the argument was + * successful or not. + * + * Most of these do their thing, then after returning + * to xxmain(), the code exits without starting a game. + * + */ + +static struct early_opt earlyopts[] = { + {ARG_DEBUG, "debug", 5, FALSE}, + {ARG_VERSION, "version", 4, TRUE}, +}; + +boolean +argcheck(argc, argv, e_arg) +int argc; +char *argv[]; +enum earlyarg e_arg; +{ + int i, idx; + boolean match = FALSE; + char *userea = (char *)0, *dashdash = ""; + + for (idx = 0; idx < SIZE(earlyopts); idx++) { + if (earlyopts[idx].e == e_arg) + break; + } + if ((idx >= SIZE(earlyopts)) || (argc <= 1)) + return FALSE; + + for (i = 1; i < argc; ++i) { + if (argv[i][0] != '-') + continue; + if (argv[i][1] == '-') { + userea = &argv[i][2]; + dashdash = "-"; + } else { + userea = &argv[i][1]; + } + match = match_optname(userea, earlyopts[idx].name, + earlyopts[idx].minlength, earlyopts[idx].valallowed); + if (match) break; + } + + if (match) { + switch(e_arg) { + case ARG_DEBUG: + break; + case ARG_VERSION: { + boolean insert_into_pastebuf = FALSE; + const char *extended_opt = index(userea,':'); + + if (!extended_opt) + extended_opt = index(userea, '='); + + if (extended_opt) { + extended_opt++; + if (match_optname(extended_opt, "paste", + 5, FALSE)) { + insert_into_pastebuf = TRUE; + } else { + raw_printf( + "-%sversion can only be extended with -%sversion:paste.\n", + dashdash, dashdash); + return TRUE; + } + } + early_version_info(insert_into_pastebuf); + return TRUE; + break; + } + default: + break; + } + }; + return FALSE; +} /*allmain.c*/ diff --git a/src/version.c b/src/version.c index 19f74c265..514665663 100644 --- a/src/version.c +++ b/src/version.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 version.c $NHDT-Date: 1506993902 2017/10/03 01:25:02 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.44 $ */ +/* NetHack 3.6 version.c $NHDT-Date: 1517140532 2018/01/28 11:55:32 $ $NHDT-Branch: nhmall-githash3 $:$NHDT-Revision: 1.50 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -15,6 +15,13 @@ #include "patchlevel.h" #endif +#if defined(NETHACK_GIT_SHA) +const char * NetHack_git_sha = NETHACK_GIT_SHA; +#endif +#if defined(NETHACK_GIT_BRANCH) +const char * NetHack_git_branch = NETHACK_GIT_BRANCH; +#endif + STATIC_DCL void FDECL(insert_rtoption, (char *)); /* fill buffer with short version (so caller can avoid including date.h) */ @@ -30,23 +37,34 @@ char * getversionstring(buf) char *buf; { - int details = 0; + boolean details = FALSE; Strcpy(buf, VERSION_ID); -#if defined(RUNTIME_PORT_ID) - details++; +#if defined(RUNTIME_PORT_ID) || \ + defined(NETHACK_GIT_SHA) || defined(NETHACK_GIT_BRANCH) + details = TRUE; #endif if (details) { int c = 0; +#if defined(RUNTIME_PORT_ID) char tmpbuf[BUFSZ]; char *tmp = (char *)0; +#endif Sprintf(eos(buf), " ("); #if defined(RUNTIME_PORT_ID) tmp = get_port_id(tmpbuf); if (tmp) Sprintf(eos(buf), "%s%s", c++ ? "," : "", tmp); +#endif +#if defined(NETHACK_GIT_SHA) + if (NetHack_git_sha) + Sprintf(eos(buf), "%s%s", c++ ? "," : "", NetHack_git_sha); +#endif +#if defined(NETHACK_GIT_BRANCH) + if (NetHack_git_branch) + Sprintf(eos(buf), "%s%s", c++ ? "," : "", NetHack_git_branch); #endif Sprintf(eos(buf), ")"); } @@ -130,6 +148,37 @@ doextversion() return 0; } +void early_version_info(pastebuf) +boolean pastebuf; +{ + char buf[BUFSZ], buf2[BUFSZ]; + char *tmp = getversionstring(buf); + + /* this is early enough that we have to do + our own line-splitting */ + if (tmp) { + tmp = strstri(buf," ("); + if (tmp) *tmp++ = '\0'; + } + + Sprintf(buf2, "%s\n", buf); + if (tmp) Sprintf(eos(buf2), "%s\n", tmp); + raw_printf("%s", buf2); + + if (pastebuf) { +#ifdef RUNTIME_PASTEBUF_SUPPORT + /* + * Call a platform/port-specific routine to insert the + * version information into a paste buffer. Useful for + * easy inclusion in bug reports. + */ + port_insert_pastebuf(buf2); +#else + raw_printf("%s", "Paste buffer copy is not available.\n"); +#endif + } +} + extern const char regex_id[]; /* diff --git a/sys/share/pcmain.c b/sys/share/pcmain.c index a18157639..64a175c14 100644 --- a/sys/share/pcmain.c +++ b/sys/share/pcmain.c @@ -329,6 +329,9 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/ Strcpy(hackdir, HACKDIR); #endif if (argc > 1) { + if (argcheck(argc, argv, ARG_VERSION)) + nethack_exit(EXIT_SUCCESS); + if (!strncmp(argv[1], "-d", 2) && argv[1][2] != 'e') { /* avoid matching "-dec" for DECgraphics; since the man page * says -d directory, hope nobody's using -desomething_else diff --git a/sys/unix/unixmain.c b/sys/unix/unixmain.c index b9ab44526..95e48cc14 100644 --- a/sys/unix/unixmain.c +++ b/sys/unix/unixmain.c @@ -110,6 +110,9 @@ char *argv[]; dir = nh_getenv("HACKDIR"); if (argc > 1) { + if (argcheck(argc, argv, ARG_VERSION)) + exit(EXIT_SUCCESS); + if (!strncmp(argv[1], "-d", 2) && argv[1][2] != 'e') { /* avoid matching "-dec" for DECgraphics; since the man page * says -d directory, hope nobody's using -desomething_else @@ -720,4 +723,40 @@ get_login_name() return buf; } +#ifdef __APPLE__ +extern int errno; + +void +port_insert_pastebuf(buf) +char *buf; +{ + /* This should be replaced when there is a Cocoa port. */ + const char *errfmt; + size_t len; + FILE *PB = popen("/usr/bin/pbcopy","w"); + if(!PB){ + errfmt = "Unable to start pbcopy (%d)\n"; + goto error; + } + + len = strlen(buf); + /* Remove the trailing \n, carefully. */ + if(buf[len-1] == '\n') len--; + + /* XXX Sorry, I'm too lazy to write a loop for output this short. */ + if(len!=fwrite(buf,1,len,PB)){ + errfmt = "Error sending data to pbcopy (%d)\n"; + goto error; + } + + if(pclose(PB)!=-1){ + return; + } + errfmt = "Error finishing pbcopy (%d)\n"; + +error: + raw_printf(errfmt,strerror(errno)); +} +#endif + /*unixmain.c*/ diff --git a/sys/winnt/winnt.c b/sys/winnt/winnt.c index 842bfd036..cfd27acac 100644 --- a/sys/winnt/winnt.c +++ b/sys/winnt/winnt.c @@ -35,6 +35,9 @@ /* globals required within here */ HANDLE ffhandle = (HANDLE) 0; WIN32_FIND_DATA ffd; +typedef HWND(WINAPI *GETCONSOLEWINDOW)(); +static HWND GetConsoleHandle(void); +static HWND GetConsoleHwnd(void); /* The function pointer nt_kbhit contains a kbhit() equivalent * which varies depending on which window port is active. @@ -316,6 +319,119 @@ int interjection_type; msmsg(interjection_buf[interjection_type]); } +#ifdef RUNTIME_PASTEBUF_SUPPORT + +void port_insert_pastebuf(buf) +char *buf; +{ + /* This implementation will utilize the windows clipboard + * to accomplish this. + */ + + char *tmp = buf; + HWND hwndConsole = GetConsoleHandle(); + HGLOBAL hglbCopy; + WCHAR *w, w2[2]; + int cc, rc, abytes; + LPWSTR lpwstrCopy; + HANDLE hresult; + + if (!buf || (hwndConsole == NULL)) + return; + + cc = strlen(buf); + /* last arg=0 means "tell me the size of the buffer that I need" */ + rc = MultiByteToWideChar(GetConsoleOutputCP(), 0, buf, -1, w2, 0); + if (!rc) return; + + abytes = rc * sizeof(WCHAR); + w = (WCHAR *)alloc(abytes); + /* Housekeeping need: +free(w) */ + + rc = MultiByteToWideChar(GetConsoleOutputCP(), 0, buf, -1, w, rc); + if (!rc) { + free(w); + return; + } + if (!OpenClipboard(hwndConsole)) { + free(w); + return; + } + /* Housekeeping need: +CloseClipboard(), free(w) */ + + EmptyClipboard(); + + /* allocate global mem obj to hold the text */ + + hglbCopy = GlobalAlloc(GMEM_MOVEABLE, abytes); + if (hglbCopy == NULL) { + CloseClipboard(); + free(w); + return; + } + /* Housekeeping need: +GlobalFree(hglbCopy), CloseClipboard(), free(w) */ + + lpwstrCopy = (LPWSTR)GlobalLock(hglbCopy); + /* Housekeeping need: +GlobalUnlock(hglbCopy), GlobalFree(hglbCopy), + CloseClipboard(), free(w) */ + + memcpy(lpwstrCopy, w, abytes); + GlobalUnlock(hglbCopy); + /* Housekeeping need: GlobalFree(hglbCopy), CloseClipboard(), free(w) */ + + /* put it on the clipboard */ + hresult = SetClipboardData(CF_UNICODETEXT, hglbCopy); + if (!hresult) { + raw_printf("Error copying to clipboard.\n"); + GlobalFree(hglbCopy); /* only needed if clipboard didn't accept data */ + } + /* Housekeeping need: CloseClipboard(), free(w) */ + + CloseClipboard(); + free(w); + return; +} + +static HWND +GetConsoleHandle(void) +{ + HMODULE hMod = GetModuleHandle("kernel32.dll"); + GETCONSOLEWINDOW pfnGetConsoleWindow = + (GETCONSOLEWINDOW) GetProcAddress(hMod, "GetConsoleWindow"); + if (pfnGetConsoleWindow) + return pfnGetConsoleWindow(); + else + return GetConsoleHwnd(); +} + +static HWND +GetConsoleHwnd(void) +{ + int iterations = 0; + HWND hwndFound = 0; + char OldTitle[1024], NewTitle[1024], TestTitle[1024]; + + /* Get current window title */ + GetConsoleTitle(OldTitle, sizeof OldTitle); + + (void) sprintf(NewTitle, "NETHACK%d/%d", GetTickCount(), + GetCurrentProcessId()); + SetConsoleTitle(NewTitle); + + GetConsoleTitle(TestTitle, sizeof TestTitle); + while (strcmp(TestTitle, NewTitle) != 0) { + iterations++; + /* sleep(0); */ + GetConsoleTitle(TestTitle, sizeof TestTitle); + } + hwndFound = FindWindow(NULL, NewTitle); + SetConsoleTitle(OldTitle); + /* printf("%d iterations\n", iterations); */ + return hwndFound; +} + +#endif + #ifdef RUNTIME_PORT_ID /* * _M_IX86 is Defined for x86 processors. This is not defined for x64 diff --git a/util/makedefs.c b/util/makedefs.c index f3f7135be..2726816e8 100644 --- a/util/makedefs.c +++ b/util/makedefs.c @@ -72,6 +72,7 @@ static const char SCCS_Id[] = "@(#)makedefs.c\t3.6\t2016/02/12"; #define QTXT_O_FILE "quest.dat" #define VIS_TAB_H "vis_tab.h" #define VIS_TAB_C "vis_tab.c" +#define GITINFO_FILE "gitinfo.txt" /* locations for those files */ #ifdef AMIGA #define FILE_PREFIX @@ -177,6 +178,7 @@ static char *FDECL(bannerc_string, (char *, const char *)); static char *FDECL(xcrypt, (const char *)); static unsigned long FDECL(read_rumors_file, (const char *, int *, long *, unsigned long)); +static boolean FDECL(get_gitinfo, (char *, char *)); static void FDECL(do_rnd_access_file, (const char *)); static boolean FDECL(d_filter, (char *)); static boolean FDECL(h_filter, (char *)); @@ -209,6 +211,7 @@ static char *FDECL(fgetline, (FILE*)); static char *FDECL(tmpdup, (const char *)); static char *FDECL(limit, (char *, int)); static char *FDECL(eos, (char *)); +static int FDECL(case_insensitive_comp, (const char *, const char *)); /* input, output, tmp */ static FILE *ifp, *ofp, *tfp; @@ -1239,6 +1242,7 @@ do_date() #else time_t clocktim = 0; #endif + char githash[BUFSZ], gitbranch[BUFSZ]; char *c, cbuf[60], buf[BUFSZ]; const char *ul_sfx; @@ -1372,6 +1376,10 @@ do_date() Fprintf(ofp, "#define COPYRIGHT_BANNER_C \\\n \"%s\"\n", bannerc_string(buf, cbuf)); Fprintf(ofp, "\n"); + if (get_gitinfo(githash, gitbranch)) { + Fprintf(ofp, "#define NETHACK_GIT_SHA \"%s\"\n", githash); + Fprintf(ofp, "#define NETHACK_GIT_BRANCH \"%s\"\n", gitbranch); + } #ifdef AMIGA { struct tm *tm = localtime((time_t *) &clocktim); @@ -1386,6 +1394,84 @@ do_date() return; } +boolean +get_gitinfo(githash, gitbranch) +char *githash, *gitbranch; +{ + FILE *gifp; + size_t len; + char infile[600]; + char *line, *strval, *opt, *c, *end; + boolean havebranch = FALSE, havehash = FALSE; + + if (!githash || !gitbranch) return FALSE; + + Sprintf(infile, DATA_IN_TEMPLATE, GITINFO_FILE); + if (!(gifp = fopen(infile, RDTMODE))) { + /* perror(infile); */ + return FALSE; + } + + /* read the gitinfo file */ + while ((line = fgetline(gifp)) != 0) { + strval = index(line, '='); + if (strval && strlen(strval) < (BUFSZ-1)) { + opt = line; + *strval++ = '\0'; + /* strip off the '\n' */ + if ((c = index(strval, '\n')) != 0) + *c = '\0'; + if ((c = index(opt, '\n')) != 0) + *c = '\0'; + /* strip leading and trailing white space */ + while (*strval == ' ' || *strval == '\t') + strval++; + end = eos(strval); + while (--end >= strval && (*end == ' ' || *end == '\t')) + *end = '\0'; + while (*opt == ' ' || *opt == '\t') + opt++; + end = eos(opt); + while (--end >= opt && (*end == ' ' || *end == '\t')) + *end = '\0'; + + len = strlen(opt); + if ((len >= strlen("gitbranch")) && !case_insensitive_comp(opt, "gitbranch")) { + Strcpy(gitbranch, strval); + havebranch = TRUE; + } + if ((len >= strlen("githash")) && !case_insensitive_comp(opt, "githash")) { + Strcpy(githash, strval); + havehash = TRUE; + } + } + } + Fclose(gifp); + if (havebranch && havehash) + return TRUE; + return FALSE; +} + +static int +case_insensitive_comp(s1, s2) +const char *s1; +const char *s2; +{ + uchar u1, u2; + + for (;; s1++, s2++) { + u1 = (uchar) *s1; + if (isupper(u1)) + u1 = tolower(u1); + u2 = (uchar) *s2; + if (isupper(u2)) + u2 = tolower(u2); + if (u1 == '\0' || u1 != u2) + break; + } + return u1 - u2; +} + static char save_bones_compat_buf[BUFSZ]; static void From cf9cf038f3fdefc4dc54a27c189dd46d47b82dd7 Mon Sep 17 00:00:00 2001 From: keni Date: Fri, 9 Feb 2018 11:48:04 -0500 Subject: [PATCH 2/4] gitinfo.pl: special case code to allow running it from $TOP or DEVEL without installing the hooks first NHgithook.pm: add some warnings if nhversioning can't open files make sure nhversioning fails before opening gitinfo.txt if it can't get valid data --- DEVEL/gitinfo.pl | 7 +++++++ DEVEL/hooksdir/.NHgithook.pm.swp | Bin 16384 -> 0 bytes DEVEL/hooksdir/NHgithook.pm | 7 ++++++- src/allmain.c | 5 +++-- src/version.c | 4 +++- sys/unix/hints/macosx.sh | 2 +- 6 files changed, 20 insertions(+), 5 deletions(-) delete mode 100644 DEVEL/hooksdir/.NHgithook.pm.swp diff --git a/DEVEL/gitinfo.pl b/DEVEL/gitinfo.pl index b62428975..d62f1a588 100644 --- a/DEVEL/gitinfo.pl +++ b/DEVEL/gitinfo.pl @@ -20,6 +20,13 @@ BEGIN { $gitdir = `git rev-parse --git-dir`; chomp $gitdir; push(@INC, $gitdir.$PDS."hooks"); + + # special case for this script only: allow + # it to run from DEVEL or $TOP + if (-f "hooksdir/NHgithook.pm" || -f "DEVEL/hooksdir/NHgithook.pm"){ + push(@INC, "DEVEL/hooksdir"); + } + chdir("..") if (-f "hooksdir/NHgithook.pm"); } use NHgithook; diff --git a/DEVEL/hooksdir/.NHgithook.pm.swp b/DEVEL/hooksdir/.NHgithook.pm.swp deleted file mode 100644 index 19e7ec87309c69aa584791723a272d5c995f868d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 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 Id21;C1L-bjZU6uP diff --git a/DEVEL/hooksdir/NHgithook.pm b/DEVEL/hooksdir/NHgithook.pm index 1bb92cf7e..0d586cfb7 100644 --- a/DEVEL/hooksdir/NHgithook.pm +++ b/DEVEL/hooksdir/NHgithook.pm @@ -1,7 +1,7 @@ # # NHgithook.pm # NetHack Git Hook Module -# $NHDT-Date$ +# $NHDT-Date: 1519164205 2018/02/20 22:03:25 $ package NHgithook; use Cwd; @@ -72,6 +72,7 @@ sub nhversioning { $git_sha =~ s/\s+//g; my $git_branch = `git rev-parse --abbrev-ref HEAD`; $git_branch =~ s/\s+//g; + die "git rev-parse failed" unless(length $git_sha and length $git_branch); if (open my $fh, '<', 'dat/gitinfo.txt') { while(my $line = <$fh>) { @@ -82,11 +83,15 @@ sub nhversioning { } } close $fh; + } else { + print "WARNING: Can't find dat directory\n" unless(-d "dat"); } if (open my $fh, '>', 'dat/gitinfo.txt') { print $fh 'githash='.$git_sha."\n"; print $fh 'gitbranch='.$git_branch."\n"; print "An updated dat/gitinfo.txt was written, githash=".$git_sha."\n"; + } else { + print "WARNING: Unable to open dat/gitinfo.txt: $!\n"; } } diff --git a/src/allmain.c b/src/allmain.c index 789c5d48f..eab1fce3d 100644 --- a/src/allmain.c +++ b/src/allmain.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 allmain.c $NHDT-Date: 1513130016 2017/12/13 01:53:36 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.81 $ */ +/* NetHack 3.6 allmain.c $NHDT-Date: 1518193644 2018/02/09 16:27:24 $ $NHDT-Branch: githash $:$NHDT-Revision: 1.86 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -763,7 +763,8 @@ enum earlyarg e_arg; { int i, idx; boolean match = FALSE; - char *userea = (char *)0, *dashdash = ""; + char *userea = (char *)0; + const char *dashdash = ""; for (idx = 0; idx < SIZE(earlyopts); idx++) { if (earlyopts[idx].e == e_arg) diff --git a/src/version.c b/src/version.c index 514665663..30e4ce75f 100644 --- a/src/version.c +++ b/src/version.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 version.c $NHDT-Date: 1517140532 2018/01/28 11:55:32 $ $NHDT-Branch: nhmall-githash3 $:$NHDT-Revision: 1.50 $ */ +/* NetHack 3.6 version.c $NHDT-Date: 1519155525 2018/02/20 19:38:45 $ $NHDT-Branch: githash $:$NHDT-Revision: 1.47 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -46,7 +46,9 @@ char *buf; #endif if (details) { +#if defined(RUNTIME_PORT_ID) || defined(NETHACK_GIT_SHA) || defined(NETHACK_GIT_BRANCH) int c = 0; +#endif #if defined(RUNTIME_PORT_ID) char tmpbuf[BUFSZ]; char *tmp = (char *)0; diff --git a/sys/unix/hints/macosx.sh b/sys/unix/hints/macosx.sh index 93e28ca51..c6cf10c31 100755 --- a/sys/unix/hints/macosx.sh +++ b/sys/unix/hints/macosx.sh @@ -1,5 +1,5 @@ #!/bin/sh -# NetHack 3.6 macosx.sh $NHDT-Date: 1518800856 2018/02/16 17:07:36 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.19 $ +# NetHack 3.6 macosx.sh $NHDT-Date: 1517231957 2018/01/29 13:19:17 $ $NHDT-Branch: githash $:$NHDT-Revision: 1.20 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2007. # NetHack may be freely redistributed. See license for details. # From c8196b645144fb2952a066f66b3e1c3635bfd985 Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 20 Feb 2018 21:08:44 -0500 Subject: [PATCH 3/4] a documentation bit --- DEVEL/Developer.txt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/DEVEL/Developer.txt b/DEVEL/Developer.txt index 1316f23e0..b896e707a 100644 --- a/DEVEL/Developer.txt +++ b/DEVEL/Developer.txt @@ -25,6 +25,7 @@ CONTENTS 5. variable expansion 6. reserved names 7. nhadd/nhcommit +8. DEVEL hooks ------------------------------------------------------------------------------ 1. email Email to devteam@nethack.org will usually get a response, but it may take a @@ -212,3 +213,14 @@ D. Using your own hooks "perldoc DEVEL/hooksdir/nhsub". ------------------------------------------------------------------------------ +8. DEVEL hooks + + If you copy DEVEL/hooksdir/* into .git/hooks, you'll benefit from + having a new dat/gitinfo.txt created for several common git operations + that are likely to result in a new git sha. During the nethack build + process, makedefs will transform the values contained in + dat/gitinfo.txt into #define's in include/date.h which the NetHack + source will utilize. + +------------------------------------------------------------------------------ + From cd96394ccd447a4d58dde6e0ef6f21ec357bf1c9 Mon Sep 17 00:00:00 2001 From: keni Date: Wed, 21 Feb 2018 10:58:31 -0500 Subject: [PATCH 4/4] Update docs, man page. Add last chance attempt to build dat/gitinfo.txt --- DEVEL/Developer.txt | 29 ++++++++++++++++++----------- README | 5 ++++- doc/nethack.6 | 8 ++++---- doc/nethack.txt | 2 +- sys/unix/Makefile.src | 5 ++++- 5 files changed, 31 insertions(+), 18 deletions(-) diff --git a/DEVEL/Developer.txt b/DEVEL/Developer.txt index b896e707a..e9b943499 100644 --- a/DEVEL/Developer.txt +++ b/DEVEL/Developer.txt @@ -4,7 +4,7 @@ |___/\___|\_/\___|_\___/ .__/\___|_| |_| -$NHDT-Date: 1518800857 2018/02/16 17:07:37 $ +$NHDT-Date: 1519228647 2018/02/21 15:57:27 $ Welcome to the NetHack Infrastructure Developer's Guide. @@ -25,7 +25,7 @@ CONTENTS 5. variable expansion 6. reserved names 7. nhadd/nhcommit -8. DEVEL hooks +8. hooks ------------------------------------------------------------------------------ 1. email Email to devteam@nethack.org will usually get a response, but it may take a @@ -39,7 +39,8 @@ available can be obtained via git from either of two locations: or https://sourceforge.net/p/nethack/NetHack/ -XXX need to discuss what branches are available +Branches: +NetHack-3.6.0 The 3.6.0 release code and subsequent fixes and additions. ------------------------------------------------------------------------------ 3. bug reporting Please use the form at http://www.nethack.org/common/contact.html (or send @@ -96,7 +97,8 @@ C. Configure the repository: -v verbose -n dry run You can re-run nhgitset.pl as often as needed; occasionally we will - update it and ask you to run it again. + update it (or something it installs) and you will need to run it again + so the changes take effect. D. aliases Two aliases are installed by nhgitset.pl: nhadd @@ -213,14 +215,19 @@ D. Using your own hooks "perldoc DEVEL/hooksdir/nhsub". ------------------------------------------------------------------------------ -8. DEVEL hooks +8. hooks - If you copy DEVEL/hooksdir/* into .git/hooks, you'll benefit from - having a new dat/gitinfo.txt created for several common git operations - that are likely to result in a new git sha. During the nethack build - process, makedefs will transform the values contained in - dat/gitinfo.txt into #define's in include/date.h which the NetHack - source will utilize. + nhgitset.pl also installs hooks into .git/hooks. These hooks provide + a framework which allows local hook code to co-exist with hook code we + supply - see DEVEL/hooksdir/NHgithook.pm for details. + + We currently use the following hooks: + post-checkout + post-commit + post-merge + These are used to generate dat/gitinfo.txt which provides the data that + ends up available through the game command #version and the command line + option --version. ------------------------------------------------------------------------------ diff --git a/README b/README index 5c4117f46..c428e146d 100644 --- a/README +++ b/README @@ -122,7 +122,10 @@ Please read items (1), (2) and (3) BEFORE doing anything with your new code. If you have problems building the game, or you find bugs in it, we recommend filing a bug report from our "Contact Us" web page at: - http://www.nethack.org/ + https://www.nethack.org/common/contact.html or + http://www.nethack.org/common/contact.html +Please include the version information from #version or the command line +option --version in the apropriate field. A public repository of the latest NetHack code that we've made available can be obtained via git here: diff --git a/doc/nethack.6 b/doc/nethack.6 index 6b38a68ba..f2ef799f1 100644 --- a/doc/nethack.6 +++ b/doc/nethack.6 @@ -1,5 +1,5 @@ .TH NETHACK 6 "7 December 2015" -.\" NetHack 3.6 nethack.6 $NHDT-Date: 1449616496 2015/12/08 23:14:56 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.11 $ +.\" NetHack 3.6 nethack.6 $NHDT-Date: 1519228609 2018/02/21 15:56:49 $ $NHDT-Branch: githash $:$NHDT-Revision: 1.13 $ .SH NAME nethack \- Exploring The Mazes of Menace .SH SYNOPSIS @@ -34,6 +34,9 @@ nethack \- Exploring The Mazes of Menace [ .B \-ibm ] +[ +.BR \-\-version [ :paste ] +] .PP .B nethack [ @@ -55,9 +58,6 @@ nethack \- Exploring The Mazes of Menace [ .I playernames ] -[ -.B \-\-version -] .ad .hy 14 .\" Make sure path is not hyphenated below diff --git a/doc/nethack.txt b/doc/nethack.txt index 9e6275edf..4c9986349 100644 --- a/doc/nethack.txt +++ b/doc/nethack.txt @@ -7,7 +7,7 @@ NAME SYNOPSIS nethack [ -d directory ] [ -n ] [ -p profession ] [ -r race ] [ -[DX] ] - [ -u playername ] [ -dec ] [ -ibm ] + [ -u playername ] [ -dec ] [ -ibm ] [ --version[:paste] ] nethack [ -d directory ] -s [ -v ] [ -p profession ] [ -r race ] [ playernames ] diff --git a/sys/unix/Makefile.src b/sys/unix/Makefile.src index 451067a93..19f41ca81 100644 --- a/sys/unix/Makefile.src +++ b/sys/unix/Makefile.src @@ -1,5 +1,5 @@ # NetHack Makefile. -# NetHack 3.6 Makefile.src $NHDT-Date: 1459122529 2016/03/27 23:48:49 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.46 $ +# NetHack 3.6 Makefile.src $NHDT-Date: 1519228664 2018/02/21 15:57:44 $ $NHDT-Branch: githash $:$NHDT-Revision: 1.51 $ # Root of source tree: NHSROOT=.. @@ -610,6 +610,9 @@ tile.c: ../win/share/tilemap.c $(HACK_H) # hack.h depends on makedefs' output, so we know makedefs will be # up to date before being executed ../include/date.h: $(VERSOURCES) $(HACK_H) + if [[ ! -f ../dat/gitinfo.txt ]]; then \ + (cd ..;perl -IDEVEL/hooksdir -MNHgithook -e '&NHgithook::nhversioning') || true; \ + fi ../util/makedefs -v