forked from NetHack/NetHack
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdate.c
More file actions
172 lines (154 loc) · 5.91 KB
/
date.c
File metadata and controls
172 lines (154 loc) · 5.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
/* NetHack 3.7 date.c $NHDT-Date: 1655402414 2022/06/16 18:00:14 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.3 $ */
/* Copyright (c) Michael Allison, 2021. */
/* NetHack may be freely redistributed. See license for details. */
#include "config.h"
/* these are in extern.h but we don't include hack.h */
void populate_nomakedefs(struct version_info *);
void free_nomakedefs(void);
#define Snprintf(str, size, ...) \
nh_snprintf(__func__, __LINE__, str, size, __VA_ARGS__)
extern void nh_snprintf(const char *func, int line, char *str, size_t size,
const char *fmt, ...);
extern unsigned long md_ignored_features(void);
extern char *mdlib_version_string(char *, const char *);
extern char *version_id_string(char *, size_t, const char *);
extern char *bannerc_string(char *, size_t, const char *);
extern int case_insensitive_comp(const char *, const char *);
/* nomakedefs_populated: flag for whether 'nomakedefs' should be freed */
static int nomakedefs_populated = 0;
struct nomakedefs_s nomakedefs = {
/* https://groups.google.com/forum/#!original/
comp.sources.games/91SfKYg_xzI/dGnR3JnspFkJ */
"Tue, 28-Jul-87 13:18:57 EDT",
"Version 1.0, built Jul 28 13:18:57 1987.",
(const char *) 0, /* git_sha */
(const char *) 0, /* git_branch */
"1.0.0-0",
"NetHack Version 1.0.0-0 - last build Tue Jul 28 13:18:57 1987.",
0x01010000UL,
0x00000000UL,
0x00000000UL,
0x00000000UL,
0x00000000UL,
0x00000000UL,
554476737UL,
};
#if defined(__DATE__) && defined(__TIME__)
#define extract_field(t,s,n,z) \
do { \
for (i = 0; i < n; ++i) \
t[i] = s[i + z]; \
t[i] = '\0'; \
} while (0)
void
populate_nomakedefs(struct version_info *version)
{
int i;
char tmpbuf1[BUFSZ], tmpbuf2[BUFSZ], *strp;
const char *mth[] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
struct tm t = {0};
time_t timeresult;
/*
* In a cross-compiled environment, you can't execute
* the target binaries during the build, so we can't
* use makedefs to write the values of the build
* date and time to a file for retrieval. Not for
* information meaningful to the target execution
* environment.
*
* How can we capture the build date/time of the target
* binaries in such a situation? We need to rely on the
* cross-compiler itself to do it for us during the
* cross-compile.
*
* To that end, we are going to make use of the
* following pre-defined preprocessor macros for this:
* gcc, msvc, clang __DATE__ "Feb 12 1996"
* gcc, msvc, clang __TIME__ "23:59:01"
*
*/
Snprintf(tmpbuf1, sizeof tmpbuf1, "%s %s", __DATE__, __TIME__);
/* "Feb 12 1996 23:59:01"
01234567890123456789 */
if ((int) strlen(tmpbuf1) == 20) {
extract_field(tmpbuf2, tmpbuf1, 4, 7); /* year */
t.tm_year = atoi(tmpbuf2) - 1900;
extract_field(tmpbuf2, tmpbuf1, 3, 0); /* mon */
for (i = 0; i < SIZE(mth); ++i)
if (!case_insensitive_comp(tmpbuf2, mth[i])) {
t.tm_mon = i;
break;
}
extract_field(tmpbuf2, tmpbuf1, 2, 4); /* mday */
strp = tmpbuf2;
if (*strp == ' ')
strp++;
t.tm_mday = atoi(strp);
extract_field(tmpbuf2, tmpbuf1, 2, 12); /* hour */
t.tm_hour = atoi(tmpbuf2);
extract_field(tmpbuf2, tmpbuf1, 2, 15); /* min */
t.tm_min = atoi(tmpbuf2);
extract_field(tmpbuf2, tmpbuf1, 2, 18); /* sec */
t.tm_sec = atoi(tmpbuf2);
timeresult = mktime(&t);
nomakedefs.build_time = (unsigned long) timeresult;
nomakedefs.build_date = dupstr(tmpbuf1);
}
nomakedefs.version_number = version->incarnation;
nomakedefs.version_features = version->feature_set;
nomakedefs.ignored_features = md_ignored_features();
nomakedefs.version_sanity1 = version->entity_count;
nomakedefs.version_sanity2 = version->struct_sizes1;
nomakedefs.version_sanity3 = version->struct_sizes2;
nomakedefs.version_string = dupstr(mdlib_version_string(tmpbuf2, "."));
nomakedefs.version_id = dupstr(
version_id_string(tmpbuf2, sizeof tmpbuf2, nomakedefs.build_date));
nomakedefs.copyright_banner_c = dupstr(
bannerc_string(tmpbuf2, sizeof tmpbuf2, nomakedefs.build_date));
#ifdef NETHACK_GIT_SHA
nomakedefs.git_sha = dupstr(NETHACK_GIT_SHA);
#endif
#ifdef NETHACK_GIT_BRANCH
nomakedefs.git_branch = dupstr(NETHACK_GIT_BRANCH);
#endif
nomakedefs_populated = 1;
return;
}
void
free_nomakedefs(void)
{
/* can't just free non-Null values because they're initialized at
compile-time with static strings and won't have dynamic values
unless populate_nomakedefs() has been called */
if (!nomakedefs_populated)
return;
if (nomakedefs.build_date)
free((genericptr_t) nomakedefs.build_date),
nomakedefs.build_date = 0;
if (nomakedefs.version_string)
free((genericptr_t) nomakedefs.version_string),
nomakedefs.version_string = 0;
if (nomakedefs.version_id)
free((genericptr_t) nomakedefs.version_id),
nomakedefs.version_id = 0;
if (nomakedefs.copyright_banner_c)
free((genericptr_t) nomakedefs.copyright_banner_c),
nomakedefs.copyright_banner_c = 0;
#ifdef NETHACK_GIT_SHA
if (nomakedefs.git_sha)
free((genericptr_t) nomakedefs.git_sha),
nomakedefs.git_sha = 0;
#endif
#ifdef NETHACK_GIT_BRANCH
if (nomakedefs.git_branch)
free((genericptr_t) nomakedefs.git_branch),
nomakedefs.git_branch = 0;
#endif
/* values are Null now; dynamic vs static doesn't really matter anymore */
nomakedefs_populated = 0;
return;
}
#endif /* __DATE__ && __TIME__ */
/*date.c*/