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-2023 */
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);
48 return strcpy(buf, JVERSION_ID);
52 /* fill and return the given buffer with the long nethack version string */
57 Strcpy(buf, VERSION_ID);
59 #if defined(RUNTIME_PORT_ID) \
60 || defined(NETHACK_GIT_SHA) || defined(NETHACK_GIT_BRANCH)
63 #if defined(RUNTIME_PORT_ID)
64 char tmpbuf[BUFSZ], *tmp;
67 boolean dotoff = (p > buf && p[-1] == '.');
72 #if defined(RUNTIME_PORT_ID)
73 tmp = get_port_id(tmpbuf);
75 Sprintf(eos(buf), "%s%s", c++ ? "," : "", tmp);
77 #if defined(NETHACK_GIT_SHA)
79 Sprintf(eos(buf), "%s%s", c++ ? "," : "", NetHack_git_sha);
81 #if defined(NETHACK_GIT_BRANCH)
82 #if (NH_DEVEL_STATUS != NH_STATUS_RELEASED)
83 if (NetHack_git_branch)
84 Sprintf(eos(buf), "%sbranch:%s",
85 c++ ? "," : "", NetHack_git_branch);
90 else /* if nothing has been added, strip " (" back off */
95 #endif /* RUNTIME_PORT_ID || NETHACK_GIT_SHA || NETHACK_GIT_BRANCH */
100 /* the 'v' command */
106 pline("%s", getversionstring(buf));
108 pline("%s", version_string_j(buf));
113 /* the '#version' command; also a choice for '?' */
118 char buf[BUFSZ], *p = 0;
119 winid win = create_nhwindow(NHW_TEXT);
121 /* instead of using ``display_file(OPTIONS_USED,TRUE)'' we handle
122 the file manually so we can include dynamic version info */
124 (void) getversionstring(buf);
125 /* if extra text (git info) is present, put it on separate line */
126 if (strlen(buf) >= COLNO)
127 p = rindex(buf, '(');
128 if (p && p > buf && p[-1] == ' ')
139 (void) version_string_j(buf);
143 f = dlb_fopen(OPTIONS_USED, "r");
146 Sprintf(buf, "[Configuration '%s' not available?]", OPTIONS_USED);
150 * already inserted above:
151 * + outdented program name and version plus build date and time
152 * dat/options; display contents with lines prefixed by '-' deleted:
154 * - indented program name and version
156 * outdented feature header
158 * indented feature list
159 * spread over multiple lines
161 * outdented windowing header
163 * indented windowing choices with
164 * optional second line for default
168 boolean prolog = TRUE; /* to skip indented program name */
170 while (dlb_fgets(buf, BUFSZ, f)) {
171 (void) strip_newline(buf);
172 if (index(buf, '\t') != 0)
173 (void) tabexpand(buf);
175 if (*buf && *buf != ' ') {
176 /* found outdented header; insert a separator since we'll
177 have skipped corresponding blank line inside the file */
181 /* skip blank lines and prolog (progame name plus version) */
186 insert_rtoption(buf);
191 (void) dlb_fclose(f);
192 display_nhwindow(win, FALSE);
193 destroy_nhwindow(win);
198 void early_version_info(pastebuf)
201 char buf[BUFSZ], buf2[BUFSZ];
202 char *tmp = getversionstring(buf);
204 /* this is early enough that we have to do
205 our own line-splitting */
207 tmp = strstri(buf," (");
208 if (tmp) *tmp++ = '\0';
211 Sprintf(buf2, "%s\n", buf);
212 if (tmp) Sprintf(eos(buf2), "%s\n", tmp);
213 raw_printf("%s", buf2);
216 #ifdef RUNTIME_PASTEBUF_SUPPORT
218 * Call a platform/port-specific routine to insert the
219 * version information into a paste buffer. Useful for
220 * easy inclusion in bug reports.
222 port_insert_pastebuf(buf2);
224 raw_printf("%s", "Paste buffer copy is not available.\n");
229 extern const char regex_id[];
232 * makedefs should put the first token into dat/options; we'll substitute
233 * the second value for it. The token must contain at least one colon
234 * so that we can spot it, and should not contain spaces so that makedefs
235 * won't split it across lines. Ideally the length should be close to
236 * that of the substituted value since we don't do phrase-splitting/line-
237 * wrapping when displaying it.
239 static struct rt_opt {
240 const char *token, *value;
242 { ":PATMATCH:", regex_id },
247 * Some optional stuff is no longer available to makedefs because
248 * it depends which of several object files got linked into the
249 * game image, so we insert those options here.
257 for (i = 0; i < SIZE(rt_opts); ++i) {
258 if (strstri(buf, rt_opts[i].token))
259 (void) strsubst(buf, rt_opts[i].token, rt_opts[i].value);
260 /* we don't break out of the loop after a match; there might be
261 other matches on the same line */
270 /* BUILD_TIME is constant but might have L suffix rather than UL;
271 'filetime' is historically signed but ought to have been unsigned */
272 return (boolean) ((unsigned long) filetime < (unsigned long) BUILD_TIME);
277 check_version(version_data, filename, complain)
278 struct version_info *version_data;
279 const char *filename;
283 #ifdef VERSION_COMPATIBILITY
284 version_data->incarnation < VERSION_COMPATIBILITY
285 || version_data->incarnation > VERSION_NUMBER
287 version_data->incarnation != VERSION_NUMBER
291 pline("Version mismatch for file \"%s\".", filename);
294 #ifndef IGNORED_FEATURES
295 version_data->feature_set != VERSION_FEATURES
297 (version_data->feature_set & ~IGNORED_FEATURES)
298 != (VERSION_FEATURES & ~IGNORED_FEATURES)
300 || version_data->entity_count != VERSION_SANITY1
301 || version_data->struct_sizes1 != VERSION_SANITY2
302 || version_data->struct_sizes2 != VERSION_SANITY3) {
304 pline("Configuration incompatibility for file \"%s\".", filename);
310 /* this used to be based on file date and somewhat OS-dependant,
311 but now examines the initial part of the file's contents */
318 struct version_info vers_info;
319 boolean verbose = name ? TRUE : FALSE;
321 rlen = read(fd, (genericptr_t) &vers_info, sizeof vers_info);
322 minit(); /* ZEROCOMP */
325 pline("File \"%s\" is empty?", name);
330 if (!check_version(&vers_info, name, verbose)) {
342 static const struct version_info version_data = {
343 VERSION_NUMBER, VERSION_FEATURES,
344 VERSION_SANITY1, VERSION_SANITY2, VERSION_SANITY3
348 /* bwrite() before bufon() uses plain write() */
349 bwrite(fd, (genericptr_t) &version_data,
350 (unsigned) (sizeof version_data));
356 const char amiga_version_string[] = AMIGA_VERSION_STRING;
360 get_feature_notice_ver(str)
364 int ver_maj, ver_min, patch;
370 str = strcpy(buf, str);
379 } else if (index("0123456789", *str) != 0) {
386 ver_maj = atoi(istr[0]);
387 ver_min = atoi(istr[1]);
388 patch = atoi(istr[2]);
389 return FEATURE_NOTICE_VER(ver_maj, ver_min, patch);
390 /* macro from hack.h */
394 get_current_feature_ver()
396 return FEATURE_NOTICE_VER(VERSION_MAJOR, VERSION_MINOR, PATCHLEVEL);
401 copyright_banner_line(indx)
404 #ifdef COPYRIGHT_BANNER_A
406 return COPYRIGHT_BANNER_A;
408 #ifdef COPYRIGHT_BANNER_B
410 return COPYRIGHT_BANNER_B;
412 #ifdef COPYRIGHT_BANNER_C
414 return COPYRIGHT_BANNER_C;
416 #ifdef COPYRIGHT_BANNER_D
418 return COPYRIGHT_BANNER_D;