miscellaneous formatting
[aNetHack.git] / src / version.c
blob7456117930a3b4e98d2b1ecd7863a48b847e16c0
1 /* NetHack 3.6 version.c $NHDT-Date: 1449328116 2015/12/05 15:08:36 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.41 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /* NetHack may be freely redistributed. See license for details. */
5 #include "hack.h"
6 #include "dlb.h"
7 #include "date.h"
8 /*
9 * All the references to the contents of patchlevel.h have been moved
10 * into makedefs....
12 #ifdef SHORT_FILENAMES
13 #include "patchlev.h"
14 #else
15 #include "patchlevel.h"
16 #endif
18 #define BETA_INFO ""
20 STATIC_DCL void FDECL(insert_rtoptions, (winid,char *,const char *));
22 /* fill buffer with short version (so caller can avoid including date.h) */
23 char *
24 version_string(buf)
25 char *buf;
27 return strcpy(buf, VERSION_STRING);
30 /* fill and return the given buffer with the long nethack version string */
31 char *
32 getversionstring(buf)
33 char *buf;
35 Strcpy(buf, VERSION_ID);
36 #if defined(BETA) && defined(BETA_INFO)
37 Sprintf(eos(buf), " %s", BETA_INFO);
38 #endif
39 #if defined(RUNTIME_PORT_ID)
40 append_port_id(buf);
41 #endif
42 return buf;
45 /* the 'v' command */
46 int
47 doversion()
49 char buf[BUFSZ];
51 pline("%s", getversionstring(buf));
52 return 0;
55 /* the '#version' command; also a choice for '?' */
56 int
57 doextversion()
59 dlb *f;
60 char *pd, buf[BUFSZ];
61 winid win = create_nhwindow(NHW_TEXT);
62 boolean rtadded = FALSE;
64 /* instead of using ``display_file(OPTIONS_USED,TRUE)'' we handle
65 the file manually so we can include dynamic version info */
66 putstr(win, 0, getversionstring(buf));
68 f = dlb_fopen(OPTIONS_USED, "r");
69 if (!f) {
70 putstr(win, 0, "");
71 Sprintf(buf, "[Configuration '%s' not available?]", OPTIONS_USED);
72 putstr(win, 0, buf);
73 } else {
75 * already inserted above:
76 * + outdented program name and version plus build date and time
77 * dat/options; display the contents with lines prefixed by '-'
78 * deleted:
79 * - blank-line
80 * - indented program name and version
81 * blank-line
82 * outdented feature header
83 * - blank-line
84 * indented feature list
85 * spread over multiple lines
86 * blank-line
87 * outdented windowing header
88 * - blank-line
89 * indented windowing choices with
90 * optional second line for default
91 * - blank-line
92 * - EOF
94 boolean prolog = TRUE; /* to skip indented program name */
96 while (dlb_fgets(buf, BUFSZ, f)) {
97 (void) strip_newline(buf);
98 if (index(buf, '\t') != 0)
99 (void) tabexpand(buf);
101 if (*buf && *buf != ' ') {
102 /* found outdented header; insert a separator since we'll
103 have skipped corresponding blank line inside the file */
104 putstr(win, 0, "");
105 prolog = FALSE;
107 /* skip blank lines and prolog (progame name plus version) */
108 if (prolog || !*buf)
109 continue;
111 if (!rtadded) {
112 const char *catchphrase = ", and basic NetHack features.";
114 pd = strstri(buf, catchphrase);
115 if (pd) {
116 *pd = '\0';
117 insert_rtoptions(win, buf, &catchphrase[2]);
118 rtadded = TRUE; /* only do it once */
121 if (*buf)
122 putstr(win, 0, buf);
124 (void) dlb_fclose(f);
125 display_nhwindow(win, FALSE);
126 destroy_nhwindow(win);
128 return 0;
131 extern const char regex_id[];
133 static const char *rt_opts[] = {
134 "pattern matching via", regex_id,
136 static const char indent[] = " ";
139 * 3.6.0
140 * Some optional stuff is no longer available to makedefs because
141 * it depends which of several object files got linked into the
142 * game image, so we insert those options here.
144 STATIC_OVL void
145 insert_rtoptions(win, buf, finalphrase)
146 winid win;
147 char *buf;
148 const char *finalphrase;
150 char rtbuf[BUFSZ];
151 int l, i;
152 const char *s1 = 0, *s2 = 0, *s3 = 0, *s4 = 0;
154 if ((int) strlen(buf) >= (BUFSZ - 1))
155 return;
157 strcpy(rtbuf, buf);
158 for (i = 0; i < (SIZE(rt_opts) + 1); i += 2) {
159 if (i < SIZE(rt_opts)) {
160 s1 = ", ";
161 s2 = rt_opts[i];
162 s3 = " ";
163 s4 = rt_opts[i+1];
164 } else {
165 s1 = " ";
166 s2 = finalphrase;
167 s3 = "";
168 s4 = "";
170 l = (int) strlen(rtbuf) + (int) strlen(s1) + (int) strlen(s2)
171 + (int) strlen(s3) + (int) strlen(s4) + 1;
172 if (l <= (COLNO - 5) && l < (BUFSZ - 1)) {
173 Strcat(rtbuf, s1);
174 Strcat(rtbuf, s2);
175 Strcat(rtbuf, s3);
176 Strcat(rtbuf, s4);
177 } else {
178 putstr(win, 0, rtbuf);
179 if (i >= SIZE(rt_opts))
180 s1 = "";
181 l = (int) strlen(indent) + (int) strlen(s1) + (int) strlen(s2)
182 + (int) strlen(s3) + (int) strlen(s4) + 1;
183 if (l <= (COLNO - 5) && l < (BUFSZ - 1)) {
184 Strcpy(rtbuf, indent);
185 Strcat(rtbuf, s1);
186 Strcat(rtbuf, s2);
187 Strcat(rtbuf, s3);
188 Strcat(rtbuf, s4);
193 if (l)
194 putstr(win, 0, rtbuf);
195 *buf = '\0';
198 #ifdef MICRO
199 boolean
200 comp_times(filetime)
201 long filetime;
203 /* BUILD_TIME is constant but might have L suffix rather than UL;
204 'filetime' is historically signed but ought to have been unsigned */
205 return (boolean) ((unsigned long) filetime < (unsigned long) BUILD_TIME);
207 #endif
209 boolean
210 check_version(version_data, filename, complain)
211 struct version_info *version_data;
212 const char *filename;
213 boolean complain;
215 if (
216 #ifdef VERSION_COMPATIBILITY
217 version_data->incarnation < VERSION_COMPATIBILITY
218 || version_data->incarnation > VERSION_NUMBER
219 #else
220 version_data->incarnation != VERSION_NUMBER
221 #endif
223 if (complain)
224 pline("Version mismatch for file \"%s\".", filename);
225 return FALSE;
226 } else if (
227 #ifndef IGNORED_FEATURES
228 version_data->feature_set != VERSION_FEATURES
229 #else
230 (version_data->feature_set & ~IGNORED_FEATURES)
231 != (VERSION_FEATURES & ~IGNORED_FEATURES)
232 #endif
233 || version_data->entity_count != VERSION_SANITY1
234 || version_data->struct_sizes1 != VERSION_SANITY2
235 || version_data->struct_sizes2 != VERSION_SANITY3) {
236 if (complain)
237 pline("Configuration incompatibility for file \"%s\".", filename);
238 return FALSE;
240 return TRUE;
243 /* this used to be based on file date and somewhat OS-dependant,
244 but now examines the initial part of the file's contents */
245 boolean
246 uptodate(fd, name)
247 int fd;
248 const char *name;
250 int rlen;
251 struct version_info vers_info;
252 boolean verbose = name ? TRUE : FALSE;
254 rlen = read(fd, (genericptr_t) &vers_info, sizeof vers_info);
255 minit(); /* ZEROCOMP */
256 if (rlen == 0) {
257 if (verbose) {
258 pline("File \"%s\" is empty?", name);
259 wait_synch();
261 return FALSE;
263 if (!check_version(&vers_info, name, verbose)) {
264 if (verbose)
265 wait_synch();
266 return FALSE;
268 return TRUE;
271 void
272 store_version(fd)
273 int fd;
275 static const struct version_info version_data = {
276 VERSION_NUMBER, VERSION_FEATURES,
277 VERSION_SANITY1, VERSION_SANITY2, VERSION_SANITY3
280 bufoff(fd);
281 /* bwrite() before bufon() uses plain write() */
282 bwrite(fd, (genericptr_t) &version_data,
283 (unsigned) (sizeof version_data));
284 bufon(fd);
285 return;
288 #ifdef AMIGA
289 const char amiga_version_string[] = AMIGA_VERSION_STRING;
290 #endif
292 unsigned long
293 get_feature_notice_ver(str)
294 char *str;
296 char buf[BUFSZ];
297 int ver_maj, ver_min, patch;
298 char *istr[3];
299 int j = 0;
301 if (!str)
302 return 0L;
303 str = strcpy(buf, str);
304 istr[j] = str;
305 while (*str) {
306 if (*str == '.') {
307 *str++ = '\0';
308 j++;
309 istr[j] = str;
310 if (j == 2)
311 break;
312 } else if (index("0123456789", *str) != 0) {
313 str++;
314 } else
315 return 0L;
317 if (j != 2)
318 return 0L;
319 ver_maj = atoi(istr[0]);
320 ver_min = atoi(istr[1]);
321 patch = atoi(istr[2]);
322 return FEATURE_NOTICE_VER(ver_maj, ver_min, patch);
323 /* macro from hack.h */
326 unsigned long
327 get_current_feature_ver()
329 return FEATURE_NOTICE_VER(VERSION_MAJOR, VERSION_MINOR, PATCHLEVEL);
332 /*ARGUSED*/
333 const char *
334 copyright_banner_line(indx)
335 int indx;
337 #ifdef COPYRIGHT_BANNER_A
338 if (indx == 1)
339 return COPYRIGHT_BANNER_A;
340 #endif
341 #ifdef COPYRIGHT_BANNER_B
342 if (indx == 2)
343 return COPYRIGHT_BANNER_B;
344 #endif
345 #ifdef COPYRIGHT_BANNER_C
346 if (indx == 3)
347 return COPYRIGHT_BANNER_C;
348 #endif
349 #ifdef COPYRIGHT_BANNER_D
350 if (indx == 4)
351 return COPYRIGHT_BANNER_D;
352 #endif
353 return "";
356 /*version.c*/