-/* NetHack 3.7 date.c $NHDT-Date: 1644524054 2022/02/10 20:14:14 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ */
+/* NetHack 3.7 date.c $NHDT-Date: 1645393645 2022/02/20 21:47:25 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ */
/* Copyright (c) Michael Allison, 2021. */
/* NetHack may be freely redistributed. See license for details. */
extern char *bannerc_string(char *, int, 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 */
"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"
- *
- */
- /* if (sizeof __DATE__ + sizeof __TIME__ + sizeof "123" <
- sizeof tmpbuf1) */
- 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;
+
+ /*
+ * 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;
#ifdef MD_IGNORED_FEATURES
- nomakedefs.ignored_features = MD_IGNORED_FEATURES;
+ nomakedefs.ignored_features = MD_IGNORED_FEATURES;
#endif
- 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(
+ 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(
+ nomakedefs.copyright_banner_c = dupstr(
bannerc_string(tmpbuf2, sizeof tmpbuf2, nomakedefs.build_date));
#ifdef NETHACK_GIT_SHA
- nomakedefs.git_sha = dupstr(NETHACK_GIT_SHA);
+ nomakedefs.git_sha = dupstr(NETHACK_GIT_SHA);
#endif
#ifdef NETHACK_GIT_BRANCH
- nomakedefs.git_branch = dupstr(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;
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__ */