gnucash maint: [gnc-features.cpp] convert to cpp
Christopher Lam
clam at code.gnucash.org
Fri Oct 28 08:51:41 EDT 2022
Updated via https://github.com/Gnucash/gnucash/commit/8192deff (commit)
from https://github.com/Gnucash/gnucash/commit/6f6d2fef (commit)
commit 8192deff37e4a5063ad62a90753bcd9a60b2f716
Author: Christopher Lam <christopher.lck at gmail.com>
Date: Tue Oct 25 00:17:30 2022 +0800
[gnc-features.cpp] convert to cpp
- don't need to create/destroy GHashTable for each feature query
- plugs leak: g_hash_table_unref (features_used) not always called properly
- to check 1 feature, don't need to traverse whole GHashTable
diff --git a/libgnucash/engine/CMakeLists.txt b/libgnucash/engine/CMakeLists.txt
index 8dde8461b..b9d11b877 100644
--- a/libgnucash/engine/CMakeLists.txt
+++ b/libgnucash/engine/CMakeLists.txt
@@ -93,6 +93,7 @@ set (engine_HEADERS
qof-backend.hpp
qofbackend.h
qofbook.h
+ qofbook.hpp
qofbookslots.h
qofchoice.h
qofclass.h
@@ -145,7 +146,7 @@ set (engine_SOURCES
gnc-datetime.cpp
gnc-engine.c
gnc-event.c
- gnc-features.c
+ gnc-features.cpp
gnc-hooks.c
gnc-int128.cpp
gnc-lot.c
diff --git a/libgnucash/engine/gnc-features.c b/libgnucash/engine/gnc-features.cpp
similarity index 53%
rename from libgnucash/engine/gnc-features.c
rename to libgnucash/engine/gnc-features.cpp
index f710677d2..5e2823a3c 100644
--- a/libgnucash/engine/gnc-features.c
+++ b/libgnucash/engine/gnc-features.cpp
@@ -19,28 +19,22 @@
* *
\********************************************************************/
+#include <unordered_map>
+#include <string>
+#include <numeric>
+
#include <config.h>
#include <glib.h>
#include <glib/gi18n.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include "qof.h"
-#include "gnc-features.h"
-#include "gnc-glib-utils.h"
+#include "qofbook.hpp"
-typedef struct
+extern "C"
{
- const gchar *key;
- const gchar *desc;
-} gncFeature;
+#include "gnc-features.h"
+}
-static GHashTable *features_table = NULL;
-static gncFeature known_features[] =
+static const FeaturesTable features_table
{
{ GNC_FEATURE_CREDIT_NOTES, "Customer and vendor credit notes (requires at least GnuCash 2.5.0)" },
{ GNC_FEATURE_NUM_FIELD_SOURCE, "User specifies source of 'num' field'; either transaction number or split action (requires at least GnuCash 2.5.0)" },
@@ -53,7 +47,6 @@ static gncFeature known_features[] =
{ GNC_FEATURE_BUDGET_UNREVERSED, "Store budget amounts unreversed (i.e. natural) signs (requires at least Gnucash 3.8)"},
{ GNC_FEATURE_BUDGET_SHOW_EXTRA_ACCOUNT_COLS, "Show extra account columns in the Budget View (requires at least Gnucash 3.8)"},
{ GNC_FEATURE_EQUITY_TYPE_OPENING_BALANCE, GNC_FEATURE_EQUITY_TYPE_OPENING_BALANCE " (requires at least Gnucash 4.3)" },
- { NULL },
};
/* This static indicates the debugging module that this .o belongs to. */
@@ -62,40 +55,11 @@ static QofLogModule log_module = G_LOG_DOMAIN;
/********************************************************************\
\********************************************************************/
-static void gnc_features_init ()
-{
- gint i;
-
- if (features_table)
- return;
-
- features_table = g_hash_table_new (g_str_hash, g_str_equal);
- for (i = 0; known_features[i].key; i++)
- g_hash_table_insert (features_table,
- g_strdup (known_features[i].key),
- g_strdup (known_features[i].desc));
-}
-
-static void gnc_features_test_one(gpointer pkey, gpointer value,
- gpointer data)
-{
- const gchar *key = (const gchar*)pkey;
- const gchar *feature_desc = (const gchar*)value;
- GList **unknown_features;
-
- g_assert(data);
- unknown_features = (GList**) data;
-
- /* Check if this feature is in the known features list. */
- if (g_hash_table_lookup_extended (features_table, key, NULL, NULL))
- return;
-
- /* It is unknown, so add the description to the unknown features list: */
- g_assert(feature_desc);
-
- *unknown_features = g_list_prepend(*unknown_features,
- (gpointer)feature_desc);
-}
+static const char*
+header = N_("This Dataset contains features not supported "
+ "by this version of GnuCash. You must use a "
+ "newer version of GnuCash in order to support "
+ "the following features:");
/* Check if the session requires features unknown to this version of GnuCash.
*
@@ -104,78 +68,31 @@ static void gnc_features_test_one(gpointer pkey, gpointer value,
*/
gchar *gnc_features_test_unknown (QofBook *book)
{
-
- GList* features_list = NULL;
- GHashTable *features_used = qof_book_get_features (book);
-
- /* Setup the known_features hash table */
- gnc_features_init();
-
- /* Iterate over the members of this frame for unknown features */
- g_hash_table_foreach (features_used, &gnc_features_test_one,
- &features_list);
- if (features_list)
- {
- const char* sep = "\n* ";
- const char* header = _("This Dataset contains features not supported "
- "by this version of GnuCash. You must use a "
- "newer version of GnuCash in order to support "
- "the following features:");
-
- char *features_str = gnc_g_list_stringjoin (features_list, sep);
- char *msg = g_strconcat (header, sep, features_str, NULL);
- g_free (features_str);
- g_list_free(features_list);
- return msg;
- }
- g_hash_table_unref (features_used);
- return NULL;
+ auto unknowns {qof_book_get_unknown_features (book, features_table)};
+ auto accum = [](const auto& a, const auto& b){ return a + "\n* " + b; };
+ return unknowns.empty() ? nullptr :
+ g_strdup (std::accumulate (unknowns.begin(), unknowns.end(),
+ std::string (_(header)), accum).c_str());
}
void gnc_features_set_used (QofBook *book, const gchar *feature)
{
- const gchar *description;
-
g_return_if_fail (book);
g_return_if_fail (feature);
- gnc_features_init();
-
/* Can't set an unknown feature */
- description = g_hash_table_lookup (features_table, feature);
- if (!description)
+ auto iter = features_table.find (feature);
+ if (iter == features_table.end ())
{
PWARN("Tried to set unknown feature as used.");
return;
}
- qof_book_set_feature (book, feature, description);
-}
-
-struct CheckFeature
-{
- gchar const * checked_feature;
- gboolean found;
-};
-
-static void gnc_features_check_feature_cb (gpointer pkey, gpointer value,
- gpointer data)
-{
- const gchar *key = (const gchar*)pkey;
- struct CheckFeature * check_data = data;
- g_assert(data);
- if (!g_strcmp0 (key, check_data->checked_feature))
- check_data->found = TRUE;
+ qof_book_set_feature (book, feature, iter->second.c_str());
}
gboolean gnc_features_check_used (QofBook *book, const gchar * feature)
{
- GHashTable *features_used = qof_book_get_features (book);
- struct CheckFeature check_data = {feature, FALSE};
- /* Setup the known_features hash table */
- gnc_features_init();
- g_hash_table_foreach (features_used, &gnc_features_check_feature_cb, &check_data);
- g_hash_table_unref (features_used);
- return check_data.found;
+ return qof_book_test_feature (book, feature);
}
diff --git a/libgnucash/engine/qofbook.cpp b/libgnucash/engine/qofbook.cpp
index ab2b01231..da4e2c843 100644
--- a/libgnucash/engine/qofbook.cpp
+++ b/libgnucash/engine/qofbook.cpp
@@ -61,6 +61,8 @@ extern "C"
// For GNC_ID_ROOT_ACCOUNT:
#include "AccountP.h"
+#include "qofbook.hpp"
+
static QofLogModule log_module = QOF_MOD_ENGINE;
#define AB_KEY "hbci"
#define AB_TEMPLATES "template-list"
@@ -1255,6 +1257,32 @@ qof_book_set_feature (QofBook *book, const gchar *key, const gchar *descr)
}
}
+std::vector<std::string>
+qof_book_get_unknown_features (QofBook *book, const FeaturesTable& features)
+{
+ std::vector<std::string> rv;
+ auto test_feature = [&](const KvpFrameImpl::map_type::value_type& feature)
+ {
+ if (features.find (feature.first) == features.end ())
+ rv.push_back (feature.second->get<const char*>());
+ };
+ auto frame = qof_instance_get_slots (QOF_INSTANCE (book));
+ auto slot = frame->get_slot({GNC_FEATURES});
+ if (slot != nullptr)
+ {
+ frame = slot->get<KvpFrame*>();
+ std::for_each (frame->begin (), frame->end (), test_feature);
+ }
+ return rv;
+}
+
+bool
+qof_book_test_feature (QofBook *book, const char *feature)
+{
+ auto frame = qof_instance_get_slots (QOF_INSTANCE (book));
+ return (frame->get_slot({GNC_FEATURES, feature}) != nullptr);
+}
+
void
qof_book_load_options (QofBook *book, GNCOptionLoad load_cb, GNCOptionDB *odb)
{
diff --git a/libgnucash/engine/qofbook.hpp b/libgnucash/engine/qofbook.hpp
new file mode 100644
index 000000000..402de1711
--- /dev/null
+++ b/libgnucash/engine/qofbook.hpp
@@ -0,0 +1,36 @@
+/********************************************************************\
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU General Public License as *
+ * published by the Free Software Foundation; either version 2 of *
+ * the License, or (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact: *
+ * *
+ * Free Software Foundation Voice: +1-617-542-5942 *
+ * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
+ * Boston, MA 02110-1301, USA gnu at gnu.org *
+ * *
+\********************************************************************/
+
+#ifndef __QOF_BOOK__HPP__
+#define __QOF_BOOK__HPP__
+
+#include <vector>
+#include <unordered_map>
+#include <string>
+
+#include "qof.h"
+
+using FeaturesTable = std::unordered_map<std::string,std::string>;
+
+std::vector<std::string>
+qof_book_get_unknown_features (QofBook *book, const FeaturesTable& features);
+bool qof_book_test_feature (QofBook*, const char*);
+
+#endif /* QOF_BOOK_HPP */
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 6c9be8e2c..3d2a0e7b3 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -641,7 +641,7 @@ libgnucash/engine/gncEmployee.c
libgnucash/engine/gnc-engine.c
libgnucash/engine/gncEntry.c
libgnucash/engine/gnc-event.c
-libgnucash/engine/gnc-features.c
+libgnucash/engine/gnc-features.cpp
libgnucash/engine/gnc-hooks.c
libgnucash/engine/gncIDSearch.c
libgnucash/engine/gnc-int128.cpp
Summary of changes:
libgnucash/engine/CMakeLists.txt | 3 +-
.../engine/{gnc-features.c => gnc-features.cpp} | 129 ++++-----------------
libgnucash/engine/qofbook.cpp | 28 +++++
libgnucash/engine/{gnc-session.h => qofbook.hpp} | 17 ++-
po/POTFILES.in | 2 +-
5 files changed, 67 insertions(+), 112 deletions(-)
rename libgnucash/engine/{gnc-features.c => gnc-features.cpp} (53%)
copy libgnucash/engine/{gnc-session.h => qofbook.hpp} (78%)
More information about the gnucash-changes
mailing list