From: PatR Date: Sun, 20 Feb 2022 21:47:31 +0000 (-0800) Subject: memory management for 'nomakedefs' X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7000a3ff51cb22d69482ea2b1f6a27fa2e5d875c;p=nethack memory management for 'nomakedefs' The nomakedefs struct starts out with static values, then if/when populate_nomakedefs() is called, the fields are given dynamic values. free_nomakedefs() needs to know what state it's in. A big chunk of this if just formatting for indentation. --- diff --git a/src/date.c b/src/date.c index 13f6c9445..e3b8fd21f 100644 --- a/src/date.c +++ b/src/date.c @@ -1,4 +1,4 @@ -/* 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. */ @@ -17,6 +17,9 @@ extern char *version_id_string(char *, int, const char *); 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 */ @@ -54,79 +57,88 @@ populate_nomakedefs(struct version_info *version) "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; @@ -149,6 +161,10 @@ free_nomakedefs(void) 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__ */