From 2e1d852e365d8775f6b460dd23d354c1658b96e6 Mon Sep 17 00:00:00 2001 From: Berthold Stoeger Date: Thu, 29 Feb 2024 11:31:46 +0100 Subject: [PATCH] core: convert filter_constraint_data_to_string to C++ Return an std::string to avoid memory management headaches. While doing that, convert time.c to C++ so that format_datetime directly returns an std::string. Signed-off-by: Berthold Stoeger --- Subsurface-mobile.pro | 2 +- core/CMakeLists.txt | 2 +- core/filterconstraint.cpp | 20 ++++++++------------ core/filterconstraint.h | 3 ++- core/save-git.cpp | 6 ++---- core/save-xml.cpp | 6 ++---- core/subsurface-time.h | 5 ++++- core/{time.c => time.cpp} | 17 +++++++++-------- 8 files changed, 29 insertions(+), 32 deletions(-) rename core/{time.c => time.cpp} (93%) diff --git a/Subsurface-mobile.pro b/Subsurface-mobile.pro index 635dea38e..77b999295 100644 --- a/Subsurface-mobile.pro +++ b/Subsurface-mobile.pro @@ -95,7 +95,7 @@ SOURCES += subsurface-mobile-main.cpp \ core/strtod.c \ core/tag.c \ core/taxonomy.c \ - core/time.c \ + core/time.cpp \ core/trip.c \ core/units.c \ core/uemis.c \ diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 51723f4d6..6c3b51316 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -181,7 +181,7 @@ set(SUBSURFACE_CORE_LIB_SRCS tag.h taxonomy.c taxonomy.h - time.c + time.cpp timer.c timer.h trip.c diff --git a/core/filterconstraint.cpp b/core/filterconstraint.cpp index e5d5e4a60..1b4a1ef63 100644 --- a/core/filterconstraint.cpp +++ b/core/filterconstraint.cpp @@ -622,27 +622,23 @@ filter_constraint::~filter_constraint() delete data.string_list; } -extern "C" char *filter_constraint_data_to_string(const filter_constraint *c) +std::string filter_constraint_data_to_string(const filter_constraint *c) { - QString s; if (filter_constraint_is_timestamp(c->type)) { - char *from_s = format_datetime(c->data.timestamp_range.from); - char *to_s = format_datetime(c->data.timestamp_range.to); - s = QString(from_s) + ',' + QString(to_s); - free(from_s); - free(to_s); + std::string from_s = format_datetime(c->data.timestamp_range.from); + std::string to_s = format_datetime(c->data.timestamp_range.to); + return from_s + ',' + to_s; } else if (filter_constraint_is_string(c->type)) { // TODO: this obviously breaks if the strings contain ",". // That is currently not supported by the UI, but one day we might // have to escape the strings. - s = c->data.string_list->join(","); + return c->data.string_list->join(",").toStdString(); } else if (filter_constraint_is_multiple_choice(c->type)) { - s = QString::number(c->data.multiple_choice); + return std::to_string(c->data.multiple_choice); } else { - s = QString::number(c->data.numerical_range.from) + ',' + - QString::number(c->data.numerical_range.to); + return std::to_string(c->data.numerical_range.from) + ',' + + std::to_string(c->data.numerical_range.to); } - return copy_qstring(s); } void filter_constraint_set_stringlist(filter_constraint &c, const QString &s) diff --git a/core/filterconstraint.h b/core/filterconstraint.h index f67e5de08..b906a8e03 100644 --- a/core/filterconstraint.h +++ b/core/filterconstraint.h @@ -116,7 +116,6 @@ extern bool filter_constraint_has_date_widget(enum filter_constraint_type); extern bool filter_constraint_has_time_widget(enum filter_constraint_type); extern int filter_constraint_num_decimals(enum filter_constraint_type); extern bool filter_constraint_is_valid(const struct filter_constraint *constraint); -extern char *filter_constraint_data_to_string(const struct filter_constraint *constraint); // caller takes ownership of returned string #ifdef __cplusplus } @@ -152,6 +151,8 @@ void filter_constraint_set_timestamp_from(filter_constraint &c, timestamp_t from void filter_constraint_set_timestamp_to(filter_constraint &c, timestamp_t to); // convert according to current units (metric or imperial) void filter_constraint_set_multiple_choice(filter_constraint &c, uint64_t); bool filter_constraint_match_dive(const filter_constraint &c, const struct dive *d); +std::string filter_constraint_data_to_string(const struct filter_constraint *constraint); // caller takes ownership of returned string + #endif #endif diff --git a/core/save-git.cpp b/core/save-git.cpp index 4112b217e..e836c9f30 100644 --- a/core/save-git.cpp +++ b/core/save-git.cpp @@ -957,7 +957,6 @@ static void format_one_filter_constraint(int preset_id, int constraint_id, struc { const struct filter_constraint *constraint = filter_preset_constraint(preset_id, constraint_id); const char *type = filter_constraint_type_to_string(constraint->type); - char *data; show_utf8(b, "constraint type=", type, ""); if (filter_constraint_has_string_mode(constraint->type)) { @@ -970,9 +969,8 @@ static void format_one_filter_constraint(int preset_id, int constraint_id, struc } if (constraint->negate) put_format(b, " negate"); - data = filter_constraint_data_to_string(constraint); - show_utf8(b, " data=", data, "\n"); - free(data); + std::string data = filter_constraint_data_to_string(constraint); + show_utf8(b, " data=", data.c_str(), "\n"); } /* diff --git a/core/save-xml.cpp b/core/save-xml.cpp index 89818d439..78cc8d043 100644 --- a/core/save-xml.cpp +++ b/core/save-xml.cpp @@ -657,7 +657,6 @@ static void save_filter_presets(struct membuffer *b) free(fulltext); for (int j = 0; j < filter_preset_constraint_count(i); j++) { - char *data; const struct filter_constraint *constraint = filter_preset_constraint(i, j); const char *type = filter_constraint_type_to_string(constraint->type); put_format(b, " negate) put_format(b, " negate='1'"); put_format(b, ">"); - data = filter_constraint_data_to_string(constraint); - show_utf8(b, data, "", "", 0); - free(data); + std::string data = filter_constraint_data_to_string(constraint); + show_utf8(b, data.c_str(), "", "", 0); put_format(b, "\n"); } put_format(b, " \n"); diff --git a/core/subsurface-time.h b/core/subsurface-time.h index 097aa5215..10dc92e51 100644 --- a/core/subsurface-time.h +++ b/core/subsurface-time.h @@ -16,12 +16,15 @@ extern int utc_weekday(timestamp_t timestamp); /* parse and format date times of the form YYYY-MM-DD hh:mm:ss */ extern timestamp_t parse_datetime(const char *s); /* returns 0 on error */ -extern char *format_datetime(timestamp_t timestamp); /* ownership of string passed to caller */ extern const char *monthname(int mon); #ifdef __cplusplus } + +#include +std::string format_datetime(timestamp_t timestamp); /* ownership of string passed to caller */ + #endif #endif diff --git a/core/time.c b/core/time.cpp similarity index 93% rename from core/time.c rename to core/time.cpp index 5ee177fab..bf42554a6 100644 --- a/core/time.c +++ b/core/time.cpp @@ -2,6 +2,7 @@ #include "subsurface-time.h" #include "subsurface-string.h" #include "gettext.h" +#include // for QT_TRANSLATE_NOOP #include #include #include @@ -32,7 +33,7 @@ * are unnecessary once you're counting minutes (32-bit minutes: * 8000+ years). */ -void utc_mkdate(timestamp_t timestamp, struct tm *tm) +extern "C" void utc_mkdate(timestamp_t timestamp, struct tm *tm) { static const unsigned int mdays[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, @@ -99,7 +100,7 @@ void utc_mkdate(timestamp_t timestamp, struct tm *tm) tm->tm_mon = m; } -timestamp_t utc_mktime(const struct tm *tm) +extern "C" timestamp_t utc_mktime(const struct tm *tm) { static const int mdays[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 @@ -146,7 +147,7 @@ timestamp_t utc_mktime(const struct tm *tm) * out unused calculations. If it turns out to be a bottle neck * we will have to cache a struct tm per dive. */ -int utc_year(timestamp_t timestamp) +extern "C" int utc_year(timestamp_t timestamp) { struct tm tm; utc_mkdate(timestamp, &tm); @@ -161,7 +162,7 @@ int utc_year(timestamp_t timestamp) * at throwing out unused calculations, so this is more efficient * than it looks. */ -int utc_weekday(timestamp_t timestamp) +extern "C" int utc_weekday(timestamp_t timestamp) { struct tm tm; utc_mkdate(timestamp, &tm); @@ -173,7 +174,7 @@ int utc_weekday(timestamp_t timestamp) * an 64-bit decimal and return 64-bit timestamp. On failure or * if passed an empty string, return 0. */ -extern timestamp_t parse_datetime(const char *s) +extern "C" timestamp_t parse_datetime(const char *s) { int y, m, d; int hr, min, sec; @@ -200,19 +201,19 @@ extern timestamp_t parse_datetime(const char *s) * Format 64-bit timestamp in the form "YYYY-MM-DD hh:mm:ss". * Returns the empty string for timestamp = 0 */ -extern char *format_datetime(timestamp_t timestamp) +std::string format_datetime(timestamp_t timestamp) { char buf[32]; struct tm tm; if (!timestamp) - return strdup(""); + return std::string(); utc_mkdate(timestamp, &tm); snprintf(buf, sizeof(buf), "%04u-%02u-%02u %02u:%02u:%02u", tm.tm_year, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); - return strdup(buf); + return std::string(buf); } /* Turn month (0-12) into three-character short name */