From 422f693f5be0fcb765ba090b805617736e64d57f Mon Sep 17 00:00:00 2001 From: Berthold Stoeger Date: Sun, 10 Mar 2024 17:20:59 +0100 Subject: [PATCH] core: port tag.c to C++ Let taglist_get_tagstring() return an std::string, since all callers are C++ anyway. Signed-off-by: Berthold Stoeger --- Subsurface-mobile.pro | 2 +- core/CMakeLists.txt | 2 +- core/qthelper.cpp | 6 ++--- core/{tag.c => tag.cpp} | 49 +++++++++++++++++-------------------- core/tag.h | 17 ++++++------- qt-models/divetripmodel.cpp | 8 +++--- tests/testtaglist.cpp | 29 ++++++++-------------- 7 files changed, 47 insertions(+), 66 deletions(-) rename core/{tag.c => tag.cpp} (78%) diff --git a/Subsurface-mobile.pro b/Subsurface-mobile.pro index cb9652ed9..8901b033e 100644 --- a/Subsurface-mobile.pro +++ b/Subsurface-mobile.pro @@ -93,7 +93,7 @@ SOURCES += subsurface-mobile-main.cpp \ core/sha1.c \ core/string-format.cpp \ core/strtod.c \ - core/tag.c \ + core/tag.cpp \ core/taxonomy.c \ core/time.cpp \ core/trip.c \ diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 9b177167f..63ef48f6f 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -177,7 +177,7 @@ set(SUBSURFACE_CORE_LIB_SRCS subsurfacestartup.h subsurfacesysinfo.cpp subsurfacesysinfo.h - tag.c + tag.cpp tag.h taxonomy.c taxonomy.h diff --git a/core/qthelper.cpp b/core/qthelper.cpp index 2e6536892..5246323f0 100644 --- a/core/qthelper.cpp +++ b/core/qthelper.cpp @@ -1220,10 +1220,8 @@ QStringList get_dive_gas_list(const struct dive *d) QString get_taglist_string(struct tag_entry *tag_list) { - char *buffer = taglist_get_tagstring(tag_list); - QString ret = QString::fromUtf8(buffer); - free(buffer); - return ret; + std::string tags = taglist_get_tagstring(tag_list); + return QString::fromStdString(tags); } QStringList stringToList(const QString &s) diff --git a/core/tag.c b/core/tag.cpp similarity index 78% rename from core/tag.c rename to core/tag.cpp index bf8327182..2b55048b6 100644 --- a/core/tag.c +++ b/core/tag.cpp @@ -7,6 +7,7 @@ #include "gettext.h" #include +#include // for QT_TRANSLATE_NOOP struct tag_entry *g_tag_list = NULL; @@ -23,7 +24,7 @@ static const char *default_tags[] = { /* copy an element in a list of tags */ static void copy_tl(struct tag_entry *st, struct tag_entry *dt) { - dt->tag = malloc(sizeof(struct divetag)); + dt->tag = (divetag *)malloc(sizeof(struct divetag)); dt->tag->name = copy_string(st->tag->name); dt->tag->source = copy_string(st->tag->source); } @@ -39,7 +40,7 @@ static bool tag_seen_before(struct tag_entry *start, struct tag_entry *before) } /* remove duplicates and empty nodes */ -void taglist_cleanup(struct tag_entry **tag_list) +extern "C" void taglist_cleanup(struct tag_entry **tag_list) { struct tag_entry **tl = tag_list; while (*tl) { @@ -52,27 +53,21 @@ void taglist_cleanup(struct tag_entry **tag_list) } } -char *taglist_get_tagstring(struct tag_entry *tag_list) +std::string taglist_get_tagstring(struct tag_entry *tag_list) { bool first_tag = true; - struct membuffer b = { 0 }; + std::string res; struct tag_entry *tmp = tag_list; while (tmp != NULL) { if (!empty_string(tmp->tag->name)) { - if (first_tag) { - put_format(&b, "%s", tmp->tag->name); - first_tag = false; - } else { - put_format(&b, ", %s", tmp->tag->name); - } + if (!first_tag) + res += ", "; + res += tmp->tag->name; + first_tag = false; } tmp = tmp->next; } - /* Ensures we do return null terminated empty string for: - * - empty tag list - * - tag list with empty tag only - */ - return detach_cstring(&b); + return strdup(res.c_str()); } static inline void taglist_free_divetag(struct divetag *tag) @@ -103,22 +98,22 @@ static struct divetag *taglist_add_divetag(struct tag_entry **tag_list, struct d } /* Insert in front of it */ - entry = malloc(sizeof(struct tag_entry)); + entry = (tag_entry *)malloc(sizeof(struct tag_entry)); entry->next = next; entry->tag = tag; *tag_list = entry; return tag; } -struct divetag *taglist_add_tag(struct tag_entry **tag_list, const char *tag) +extern "C" struct divetag *taglist_add_tag(struct tag_entry **tag_list, const char *tag) { size_t i = 0; int is_default_tag = 0; struct divetag *ret_tag, *new_tag; const char *translation; - new_tag = malloc(sizeof(struct divetag)); + new_tag = (divetag *)malloc(sizeof(struct divetag)); - for (i = 0; i < sizeof(default_tags) / sizeof(char *); i++) { + for (i = 0; i < std::size(default_tags); i++) { if (strcmp(default_tags[i], tag) == 0) { is_default_tag = 1; break; @@ -127,13 +122,13 @@ struct divetag *taglist_add_tag(struct tag_entry **tag_list, const char *tag) /* Only translate default tags */ if (is_default_tag) { translation = translate("gettextFromC", tag); - new_tag->name = malloc(strlen(translation) + 1); + new_tag->name = (char *)malloc(strlen(translation) + 1); memcpy(new_tag->name, translation, strlen(translation) + 1); - new_tag->source = malloc(strlen(tag) + 1); + new_tag->source = (char *)malloc(strlen(tag) + 1); memcpy(new_tag->source, tag, strlen(tag) + 1); } else { new_tag->source = NULL; - new_tag->name = malloc(strlen(tag) + 1); + new_tag->name = (char *)malloc(strlen(tag) + 1); memcpy(new_tag->name, tag, strlen(tag) + 1); } /* Try to insert new_tag into g_tag_list if we are not operating on it */ @@ -151,12 +146,12 @@ struct divetag *taglist_add_tag(struct tag_entry **tag_list, const char *tag) return ret_tag; } -void taglist_free(struct tag_entry *entry) +extern "C" void taglist_free(struct tag_entry *entry) { STRUCTURED_LIST_FREE(struct tag_entry, entry, free) } -struct tag_entry *taglist_copy(struct tag_entry *s) +extern "C" struct tag_entry *taglist_copy(struct tag_entry *s) { struct tag_entry *res; STRUCTURED_LIST_COPY(struct tag_entry, s, res, copy_tl); @@ -164,7 +159,7 @@ struct tag_entry *taglist_copy(struct tag_entry *s) } /* Merge src1 and src2, write to *dst */ -void taglist_merge(struct tag_entry **dst, struct tag_entry *src1, struct tag_entry *src2) +extern "C" void taglist_merge(struct tag_entry **dst, struct tag_entry *src1, struct tag_entry *src2) { struct tag_entry *entry; @@ -174,10 +169,10 @@ void taglist_merge(struct tag_entry **dst, struct tag_entry *src1, struct tag_en taglist_add_divetag(dst, entry->tag); } -void taglist_init_global() +extern "C" void taglist_init_global() { size_t i; - for (i = 0; i < sizeof(default_tags) / sizeof(char *); i++) + for (i = 0; i < std::size(default_tags); i++) taglist_add_tag(&g_tag_list, default_tags[i]); } diff --git a/core/tag.h b/core/tag.h index bd2642278..8628e0d80 100644 --- a/core/tag.h +++ b/core/tag.h @@ -36,15 +36,6 @@ extern struct tag_entry *g_tag_list; struct divetag *taglist_add_tag(struct tag_entry **tag_list, const char *tag); -/* - * Writes all divetags form tag_list into internally allocated buffer - * Function returns pointer to allocated buffer - * Buffer contains comma separated list of tags names or null terminated string - * - * NOTE! The returned buffer must be freed once used. - */ -char *taglist_get_tagstring(struct tag_entry *tag_list); - /* cleans up a list: removes empty tags and duplicates */ void taglist_cleanup(struct tag_entry **tag_list); @@ -55,6 +46,14 @@ void taglist_merge(struct tag_entry **dst, struct tag_entry *src1, struct tag_en #ifdef __cplusplus } + +// C++ only functions + +#include + +/* Comma separated list of tags names or null terminated string */ +std::string taglist_get_tagstring(struct tag_entry *tag_list); + #endif #endif diff --git a/qt-models/divetripmodel.cpp b/qt-models/divetripmodel.cpp index 76209f4b7..41f6a15d6 100644 --- a/qt-models/divetripmodel.cpp +++ b/qt-models/divetripmodel.cpp @@ -1766,11 +1766,9 @@ bool DiveTripModelList::lessThan(const QModelIndex &i1, const QModelIndex &i2) c case MAXCNS: return lessThanHelper(d1->maxcns - d2->maxcns, row_diff); case TAGS: { - char *s1 = taglist_get_tagstring(d1->tag_list); - char *s2 = taglist_get_tagstring(d2->tag_list); - int diff = strCmp(s1, s2); - free(s1); - free(s2); + std::string s1 = taglist_get_tagstring(d1->tag_list); + std::string s2 = taglist_get_tagstring(d2->tag_list); + int diff = strCmp(s1.c_str(), s2.c_str()); return lessThanHelper(diff, row_diff); } case PHOTOS: diff --git a/tests/testtaglist.cpp b/tests/testtaglist.cpp index cd7e59c43..6d5410daf 100644 --- a/tests/testtaglist.cpp +++ b/tests/testtaglist.cpp @@ -17,19 +17,16 @@ void TestTagList::cleanupTestCase() void TestTagList::testGetTagstringNoTags() { struct tag_entry *tag_list = NULL; - char *tagstring = taglist_get_tagstring(tag_list); - QVERIFY(tagstring != NULL); - QCOMPARE(*tagstring, '\0'); + std::string tagstring = taglist_get_tagstring(tag_list); + QVERIFY(tagstring.empty()); } void TestTagList::testGetTagstringSingleTag() { struct tag_entry *tag_list = NULL; taglist_add_tag(&tag_list, "A new tag"); - char *tagstring = taglist_get_tagstring(tag_list); - QVERIFY(tagstring != NULL); - QCOMPARE(QString::fromUtf8(tagstring), QString::fromUtf8("A new tag")); - free(tagstring); + std::string tagstring = taglist_get_tagstring(tag_list); + QCOMPARE(QString::fromStdString(tagstring), QString::fromUtf8("A new tag")); } void TestTagList::testGetTagstringMultipleTags() @@ -41,9 +38,8 @@ void TestTagList::testGetTagstringMultipleTags() taglist_add_tag(&tag_list, "A new tag 3"); taglist_add_tag(&tag_list, "A new tag 4"); taglist_add_tag(&tag_list, "A new tag 5"); - char *tagstring = taglist_get_tagstring(tag_list); - QVERIFY(tagstring != NULL); - QCOMPARE(QString::fromUtf8(tagstring), + std::string tagstring = taglist_get_tagstring(tag_list); + QCOMPARE(QString::fromStdString(tagstring), QString::fromUtf8( "A new tag, " "A new tag 1, " @@ -51,7 +47,6 @@ void TestTagList::testGetTagstringMultipleTags() "A new tag 3, " "A new tag 4, " "A new tag 5")); - free(tagstring); } void TestTagList::testGetTagstringWithAnEmptyTag() @@ -60,24 +55,20 @@ void TestTagList::testGetTagstringWithAnEmptyTag() taglist_add_tag(&tag_list, "A new tag"); taglist_add_tag(&tag_list, "A new tag 1"); taglist_add_tag(&tag_list, ""); - char *tagstring = taglist_get_tagstring(tag_list); - QVERIFY(tagstring != NULL); - QCOMPARE(QString::fromUtf8(tagstring), + std::string tagstring = taglist_get_tagstring(tag_list); + QCOMPARE(QString::fromStdString(tagstring), QString::fromUtf8( "A new tag, " "A new tag 1")); - free(tagstring); } void TestTagList::testGetTagstringEmptyTagOnly() { struct tag_entry *tag_list = NULL; taglist_add_tag(&tag_list, ""); - char *tagstring = taglist_get_tagstring(tag_list); - QVERIFY(tagstring != NULL); - QCOMPARE(QString::fromUtf8(tagstring), + std::string tagstring = taglist_get_tagstring(tag_list); + QCOMPARE(QString::fromStdString(tagstring), QString::fromUtf8("")); - free(tagstring); } QTEST_GUILESS_MAIN(TestTagList)