1 /* NetHack 3.6 version.c $NHDT-Date: 1552353060 2019/03/12 01:11:00 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.52 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /*-Copyright (c) Michael Allison, 2018. */
4 /* NetHack may be freely redistributed. See license for details. */
6 /* JNetHack Copyright */
7 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000 */
8 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2020 */
9 /* JNetHack may be freely redistributed. See license for details. */
15 * All the references to the contents of patchlevel.h have been moved
18 #ifdef SHORT_FILENAMES
20 #include "../japanese/jpatchle.h"
22 #include "patchlevel.h"
23 #include "../japanese/jpatchlevel.h"
26 #if defined(NETHACK_GIT_SHA)
27 const char *NetHack_git_sha = NETHACK_GIT_SHA;
29 #if defined(NETHACK_GIT_BRANCH)
30 const char *NetHack_git_branch = NETHACK_GIT_BRANCH;
33 STATIC_DCL void FDECL(insert_rtoption, (char *));
35 /* fill buffer with short version (so caller can avoid including date.h) */
40 return strcpy(buf, VERSION_STRING);
43 /* fill and return the given buffer with the long nethack version string */
48 Strcpy(buf, VERSION_ID);
50 #if defined(RUNTIME_PORT_ID) \
51 || defined(NETHACK_GIT_SHA) || defined(NETHACK_GIT_BRANCH)
54 #if defined(RUNTIME_PORT_ID)
55 char tmpbuf[BUFSZ], *tmp;
58 boolean dotoff = (p > buf && p[-1] == '.');
63 #if defined(RUNTIME_PORT_ID)
64 tmp = get_port_id(tmpbuf);
66 Sprintf(eos(buf), "%s%s", c++ ? "," : "", tmp);
68 #if defined(NETHACK_GIT_SHA)
70 Sprintf(eos(buf), "%s%s", c++ ? "," : "", NetHack_git_sha);
72 #if defined(NETHACK_GIT_BRANCH)
73 #if (NH_DEVEL_STATUS != NH_STATUS_RELEASED)
74 if (NetHack_git_branch)
75 Sprintf(eos(buf), "%sbranch:%s",
76 c++ ? "," : "", NetHack_git_branch);
81 else /* if nothing has been added, strip " (" back off */
86 #endif /* RUNTIME_PORT_ID || NETHACK_GIT_SHA || NETHACK_GIT_BRANCH */
97 pline("%s", getversionstring(buf));
99 pline("%s", JVERSION_ID);
104 /* the '#version' command; also a choice for '?' */
109 char buf[BUFSZ], *p = 0;
110 winid win = create_nhwindow(NHW_TEXT);
112 /* instead of using ``display_file(OPTIONS_USED,TRUE)'' we handle
113 the file manually so we can include dynamic version info */
115 (void) getversionstring(buf);
116 /* if extra text (git info) is present, put it on separate line */
117 if (strlen(buf) >= COLNO)
118 p = rindex(buf, '(');
119 if (p && p > buf && p[-1] == ' ')
129 f = dlb_fopen(OPTIONS_USED, "r");
132 Sprintf(buf, "[Configuration '%s' not available?]", OPTIONS_USED);
136 * already inserted above:
137 * + outdented program name and version plus build date and time
138 * dat/options; display contents with lines prefixed by '-' deleted:
140 * - indented program name and version
142 * outdented feature header
144 * indented feature list
145 * spread over multiple lines
147 * outdented windowing header
149 * indented windowing choices with
150 * optional second line for default
154 boolean prolog = TRUE; /* to skip indented program name */
156 while (dlb_fgets(buf, BUFSZ, f)) {
157 (void) strip_newline(buf);
158 if (index(buf, '\t') != 0)
159 (void) tabexpand(buf);
161 if (*buf && *buf != ' ') {
162 /* found outdented header; insert a separator since we'll
163 have skipped corresponding blank line inside the file */
167 /* skip blank lines and prolog (progame name plus version) */
172 insert_rtoption(buf);
177 (void) dlb_fclose(f);
178 display_nhwindow(win, FALSE);
179 destroy_nhwindow(win);
184 void early_version_info(pastebuf)
187 char buf[BUFSZ], buf2[BUFSZ];
188 char *tmp = getversionstring(buf);
190 /* this is early enough that we have to do
191 our own line-splitting */
193 tmp = strstri(buf," (");
194 if (tmp) *tmp++ = '\0';
197 Sprintf(buf2, "%s\n", buf);
198 if (tmp) Sprintf(eos(buf2), "%s\n", tmp);
199 raw_printf("%s", buf2);
202 #ifdef RUNTIME_PASTEBUF_SUPPORT
204 * Call a platform/port-specific routine to insert the
205 * version information into a paste buffer. Useful for
206 * easy inclusion in bug reports.
208 port_insert_pastebuf(buf2);
210 raw_printf("%s", "Paste buffer copy is not available.\n");
215 extern const char regex_id[];
218 * makedefs should put the first token into dat/options; we'll substitute
219 * the second value for it. The token must contain at least one colon
220 * so that we can spot it, and should not contain spaces so that makedefs
221 * won't split it across lines. Ideally the length should be close to
222 * that of the substituted value since we don't do phrase-splitting/line-
223 * wrapping when displaying it.
225 static struct rt_opt {
226 const char *token, *value;
228 { ":PATMATCH:", regex_id },
233 * Some optional stuff is no longer available to makedefs because
234 * it depends which of several object files got linked into the
235 * game image, so we insert those options here.
243 for (i = 0; i < SIZE(rt_opts); ++i) {
244 if (strstri(buf, rt_opts[i].token))
245 (void) strsubst(buf, rt_opts[i].token, rt_opts[i].value);
246 /* we don't break out of the loop after a match; there might be
247 other matches on the same line */
256 /* BUILD_TIME is constant but might have L suffix rather than UL;
257 'filetime' is historically signed but ought to have been unsigned */
258 return (boolean) ((unsigned long) filetime < (unsigned long) BUILD_TIME);
263 check_version(version_data, filename, complain)
264 struct version_info *version_data;
265 const char *filename;
269 #ifdef VERSION_COMPATIBILITY
270 version_data->incarnation < VERSION_COMPATIBILITY
271 || version_data->incarnation > VERSION_NUMBER
273 version_data->incarnation != VERSION_NUMBER
277 pline("Version mismatch for file \"%s\".", filename);
280 #ifndef IGNORED_FEATURES
281 version_data->feature_set != VERSION_FEATURES
283 (version_data->feature_set & ~IGNORED_FEATURES)
284 != (VERSION_FEATURES & ~IGNORED_FEATURES)
286 || version_data->entity_count != VERSION_SANITY1
287 || version_data->struct_sizes1 != VERSION_SANITY2
288 || version_data->struct_sizes2 != VERSION_SANITY3) {
290 pline("Configuration incompatibility for file \"%s\".", filename);
296 /* this used to be based on file date and somewhat OS-dependant,
297 but now examines the initial part of the file's contents */
304 struct version_info vers_info;
305 boolean verbose = name ? TRUE : FALSE;
307 rlen = read(fd, (genericptr_t) &vers_info, sizeof vers_info);
308 minit(); /* ZEROCOMP */
311 pline("File \"%s\" is empty?", name);
316 if (!check_version(&vers_info, name, verbose)) {
328 static const struct version_info version_data = {
329 VERSION_NUMBER, VERSION_FEATURES,
330 VERSION_SANITY1, VERSION_SANITY2, VERSION_SANITY3
334 /* bwrite() before bufon() uses plain write() */
335 bwrite(fd, (genericptr_t) &version_data,
336 (unsigned) (sizeof version_data));
342 const char amiga_version_string[] = AMIGA_VERSION_STRING;
346 get_feature_notice_ver(str)
350 int ver_maj, ver_min, patch;
356 str = strcpy(buf, str);
365 } else if (index("0123456789", *str) != 0) {
372 ver_maj = atoi(istr[0]);
373 ver_min = atoi(istr[1]);
374 patch = atoi(istr[2]);
375 return FEATURE_NOTICE_VER(ver_maj, ver_min, patch);
376 /* macro from hack.h */
380 get_current_feature_ver()
382 return FEATURE_NOTICE_VER(VERSION_MAJOR, VERSION_MINOR, PATCHLEVEL);
387 copyright_banner_line(indx)
390 #ifdef COPYRIGHT_BANNER_A
392 return COPYRIGHT_BANNER_A;
394 #ifdef COPYRIGHT_BANNER_B
396 return COPYRIGHT_BANNER_B;
398 #ifdef COPYRIGHT_BANNER_C
400 return COPYRIGHT_BANNER_C;
402 #ifdef COPYRIGHT_BANNER_D
404 return COPYRIGHT_BANNER_D;