diff --git a/gnucash/gnome-utils/gnc-main-window.c b/gnucash/gnome-utils/gnc-main-window.c index 385a216d2f..fdff025c10 100644 --- a/gnucash/gnome-utils/gnc-main-window.c +++ b/gnucash/gnome-utils/gnc-main-window.c @@ -65,6 +65,7 @@ #include "gnc-state.h" #include "gnc-ui.h" #include "gnc-ui-util.h" +#include #include "gnc-uri-utils.h" #include "gnc-version.h" #include "gnc-warnings.h" @@ -1446,7 +1447,7 @@ gnc_main_window_delete_event (GtkWidget *window, if (already_dead) return TRUE; - if (active_windows && active_windows->next) + if (gnc_list_length_cmp (active_windows, 1) > 0) { gint response; GtkWidget *dialog; @@ -1478,7 +1479,7 @@ gnc_main_window_delete_event (GtkWidget *window, return TRUE; } - if (active_windows && active_windows->next) + if (gnc_list_length_cmp (active_windows, 1) > 0) return FALSE; already_dead = gnc_main_window_quit(GNC_MAIN_WINDOW(window)); @@ -3348,7 +3349,7 @@ gnc_main_window_close_page (GncPluginPage *page) /* remove the preference callbacks from the main window */ gnc_main_window_remove_prefs (window); } - if (window && active_windows && active_windows->next) + if (window && (gnc_list_length_cmp (active_windows, 1) > 0)) gtk_widget_destroy (GTK_WIDGET(window)); } } diff --git a/gnucash/gnome/dialog-imap-editor.c b/gnucash/gnome/dialog-imap-editor.c index 966d603916..7b6d2c6db2 100644 --- a/gnucash/gnome/dialog-imap-editor.c +++ b/gnucash/gnome/dialog-imap-editor.c @@ -33,6 +33,7 @@ #include "gnc-ui.h" #include "gnc-ui-util.h" +#include #include "Account.h" #define DIALOG_IMAP_CM_CLASS "dialog-imap-edit" @@ -251,7 +252,7 @@ gnc_imap_dialog_delete (ImapDialog *imap_dialog) list = gtk_tree_selection_get_selected_rows (selection, &fmodel); // Make sure we have some rows selected - if (list == NULL) + if (!gnc_list_length_cmp (list, 0)) return; // reset the invalid map total @@ -645,7 +646,7 @@ get_imap_info (ImapDialog *imap_dialog, Account *acc, const gchar *category, con else head = IMAP_FRAME; - if (imap_list != NULL) + if (gnc_list_length_cmp (imap_list, 0)) { PINFO("List length is %d", g_list_length (imap_list)); diff --git a/gnucash/gnome/dialog-invoice.c b/gnucash/gnome/dialog-invoice.c index 4faa55df1a..b1585b59c5 100644 --- a/gnucash/gnome/dialog-invoice.c +++ b/gnucash/gnome/dialog-invoice.c @@ -50,6 +50,7 @@ #include "gncOwner.h" #include "gncInvoice.h" #include "gncInvoiceP.h" +#include #include "gncEntryLedger.h" @@ -3237,7 +3238,7 @@ multi_post_invoice_cb (GtkWindow *dialog, GList *invoice_list, gpointer user_dat gboolean test; InvoiceWindow *iw; - if (invoice_list == NULL) + if (!gnc_list_length_cmp (invoice_list, 0)) return; // Get the posting parameters for these invoices iw = gnc_ui_invoice_edit(dialog, invoice_list->data); @@ -3287,7 +3288,7 @@ multi_print_invoice_cb (GtkWindow *dialog, GList *invoice_list, gpointer user_da { struct multi_edit_invoice_data meid; - if (invoice_list == NULL) + if (!gnc_list_length_cmp (invoice_list, 0)) return; meid.user_data = user_data; diff --git a/gnucash/gnome/dialog-payment.c b/gnucash/gnome/dialog-payment.c index 20bb58c509..7cf165e827 100644 --- a/gnucash/gnome/dialog-payment.c +++ b/gnucash/gnome/dialog-payment.c @@ -32,6 +32,7 @@ #include "gnc-ui.h" #include "gnc-gui-query.h" #include "gnc-ui-util.h" +#include #include "qof.h" #include "gnc-date.h" #include "gnc-date-edit.h" @@ -1735,7 +1736,7 @@ static GList *select_txn_lots (GtkWindow *parent, Transaction *txn, Account **po /* If the txn has both APAR splits linked to a business lot and * splits that are not, issue a warning some will be discarded. */ - if (has_no_lot_apar_splits && (txn_lots != NULL)) + if (has_no_lot_apar_splits && gnc_list_length_cmp (txn_lots, 0)) { GtkWidget *dialog; char *split_str = g_strdup (""); diff --git a/gnucash/gnome/dialog-price-edit-db.c b/gnucash/gnome/dialog-price-edit-db.c index 62511ee8e0..14770a519d 100644 --- a/gnucash/gnome/dialog-price-edit-db.c +++ b/gnucash/gnome/dialog-price-edit-db.c @@ -49,6 +49,7 @@ #include "swig-runtime.h" #include "guile-mappings.h" #include "gnc-engine-guile.h" +#include #define DIALOG_PRICE_DB_CM_CLASS "dialog-price-edit-db" @@ -366,7 +367,7 @@ selection_changed_cb (GtkTreeSelection *selection, gpointer data) PricesDialog *pdb_dialog = data; GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW(pdb_dialog->remove_view)); GList *rows = gtk_tree_selection_get_selected_rows (selection, &model); - gboolean have_rows = (rows != NULL); + gboolean have_rows = (gnc_list_length_cmp (rows, 0)); change_source_flag (PRICE_REMOVE_SOURCE_COMM, have_rows, pdb_dialog); g_list_foreach (rows, (GFunc) gtk_tree_path_free, NULL); @@ -547,7 +548,7 @@ gnc_prices_dialog_add_clicked (GtkWidget *widget, gpointer data) } else if (comm_list) // selection contains price parent rows { - if (!comm_list->next) // make sure it is only one parent + if (!gnc_list_length_cmp (comm_list, 1)) // make sure it is only one parent { price = gnc_price_create (pdb_dialog->book); gnc_price_set_commodity (price, comm_list->data); diff --git a/gnucash/gnome/dialog-sx-editor.c b/gnucash/gnome/dialog-sx-editor.c index d3d5308cb0..e79e3f2ac4 100644 --- a/gnucash/gnome/dialog-sx-editor.c +++ b/gnucash/gnome/dialog-sx-editor.c @@ -63,6 +63,7 @@ #include "gnc-ui-util.h" #include "gnucash-sheet.h" #include "gnc-session.h" +#include #include "gnc-split-reg.h" @@ -579,7 +580,7 @@ gnc_sxed_check_endpoint (GncSxEditorDialog *sxed) g_date_clear (&nextDate, 1); gnc_frequency_save_to_recurrence (sxed->gncfreq, &schedule, &startDate); - if (schedule != NULL) + if (gnc_list_length_cmp (schedule, 0)) { g_date_subtract_days (&startDate, 1); recurrenceListNextInstance (schedule, &startDate, &nextDate); @@ -1766,7 +1767,7 @@ _sx_engine_event_handler (QofInstance *ent, QofEventId event_type, gpointer user book = qof_instance_get_book (QOF_INSTANCE (acct)); affected_sxes = gnc_sx_get_sxes_referencing_account (book, acct); - if (affected_sxes == NULL) + if (!gnc_list_length_cmp (affected_sxes, 0)) return; { diff --git a/gnucash/gnome/dialog-sx-editor2.c b/gnucash/gnome/dialog-sx-editor2.c index 6c95643ada..6ddb3b3a88 100644 --- a/gnucash/gnome/dialog-sx-editor2.c +++ b/gnucash/gnome/dialog-sx-editor2.c @@ -63,6 +63,7 @@ #include "gnc-ui-util.h" #include "gnc-tree-model-split-reg.h" #include "gnc-tree-control-split-reg.h" +#include #include "gnc-sx-instance-model.h" #include "dialog-sx-since-last-run.h" @@ -836,7 +837,7 @@ gnc_sxed_check_consistent (GncSxEditorDialog2 *sxed) g_date_clear (&nextDate, 1); gnc_frequency_save_to_recurrence (sxed->gncfreq, &schedule, &startDate); - if (schedule != NULL) + if (gnc_list_length_cmp (schedule, 0)) { g_date_subtract_days (&startDate, 1); recurrenceListNextInstance (schedule, &startDate, &nextDate); @@ -1704,7 +1705,7 @@ _sx_engine_event_handler (QofInstance *ent, QofEventId event_type, gpointer user book = qof_instance_get_book (QOF_INSTANCE (acct)); affected_sxes = gnc_sx_get_sxes_referencing_account (book, acct); - if (affected_sxes == NULL) + if (!gnc_list_length_cmp (affected_sxes, 0)) return; { diff --git a/gnucash/gnome/gnc-plugin-page-account-tree.c b/gnucash/gnome/gnc-plugin-page-account-tree.c index 1a6b7ff76b..4c43b16122 100644 --- a/gnucash/gnome/gnc-plugin-page-account-tree.c +++ b/gnucash/gnome/gnc-plugin-page-account-tree.c @@ -70,6 +70,7 @@ #include "window-main-summarybar.h" #include "dialog-object-references.h" #include "dialog-find-account.h" +#include /* This static indicates the debugging module that this .o belongs to. */ static QofLogModule log_module = GNC_MOD_GUI; @@ -593,7 +594,7 @@ gnc_plugin_page_account_tree_open (Account *account, GtkWindow *win) page_list = gnc_gobject_tracking_get_list(GNC_PLUGIN_PAGE_ACCOUNT_TREE_NAME); // If we have a window, look for account page in that window - if (page_list != NULL) + if (gnc_list_length_cmp (page_list, 0)) { if (win != NULL) { @@ -1500,7 +1501,7 @@ account_subaccount (Account* account) { Account* subaccount = NULL; GList *subs = gnc_account_get_children (account); - if (subs && !subs->next) + if (!gnc_list_length_cmp (subs, 1)) subaccount = subs->data; g_list_free (subs); return subaccount; diff --git a/gnucash/gnome/gnc-plugin-page-sx-list.c b/gnucash/gnome/gnc-plugin-page-sx-list.c index ed8507b5cf..218a5e0c3a 100644 --- a/gnucash/gnome/gnc-plugin-page-sx-list.c +++ b/gnucash/gnome/gnc-plugin-page-sx-list.c @@ -756,7 +756,7 @@ gnc_plugin_page_sx_list_cmd_edit (GtkAction *action, GncPluginPageSxList *page) selection = gtk_tree_view_get_selection (priv->tree_view); selected_paths = gtk_tree_selection_get_selected_rows (selection, &model); - if (selected_paths == NULL) + if (!gnc_list_length_cmp (selected_paths, 0)) { g_warning ("no selection edit."); return; @@ -792,7 +792,7 @@ gnc_plugin_page_sx_list_cmd_edit2 (GtkAction *action, GncPluginPageSxList *page) selection = gtk_tree_view_get_selection (priv->tree_view); selected_paths = gtk_tree_selection_get_selected_rows (selection, &model); - if (selected_paths == NULL) + if (!gnc_list_length_cmp (selected_paths, 0)) { g_warning ("no selection edit."); return; @@ -853,7 +853,7 @@ gnc_plugin_page_sx_list_cmd_delete (GtkAction *action, GncPluginPageSxList *page selection = gtk_tree_view_get_selection (priv->tree_view); selected_paths = gtk_tree_selection_get_selected_rows (selection, &model); - if (selected_paths == NULL) + if (!gnc_list_length_cmp (selected_paths, 0)) { g_warning ("no selection for delete."); return; diff --git a/gnucash/register/ledger-core/gnc-ledger-display.c b/gnucash/register/ledger-core/gnc-ledger-display.c index 3326ddeae5..a6c0f33c7c 100644 --- a/gnucash/register/ledger-core/gnc-ledger-display.c +++ b/gnucash/register/ledger-core/gnc-ledger-display.c @@ -37,6 +37,7 @@ #include "gnc-ledger-display.h" #include "gnc-prefs.h" #include "gnc-ui-util.h" +#include #include "split-register-control.h" #include "split-register-model.h" @@ -429,7 +430,7 @@ gnc_ledger_display_gl (void) tRoot = gnc_book_get_template_root (gnc_get_current_book()); al = gnc_account_get_descendants (tRoot); - if (al != NULL) + if (gnc_list_length_cmp (al, 0)) xaccQueryAddAccountMatch (query, al, QOF_GUID_MATCH_NONE, QOF_QUERY_AND); g_list_free (al); diff --git a/libgnucash/core-utils/gnc-glib-utils.c b/libgnucash/core-utils/gnc-glib-utils.c index e79cf7e024..7bb2ba5333 100644 --- a/libgnucash/core-utils/gnc-glib-utils.c +++ b/libgnucash/core-utils/gnc-glib-utils.c @@ -351,3 +351,13 @@ gnc_g_list_stringjoin (GList *list_of_strings, const gchar *sep) return retval; } + +gint +gnc_list_length_cmp (const GList *list, size_t len) +{ + for (GList *lst = (GList*) list;; lst = g_list_next (lst), len--) + { + if (!lst) return (len ? -1 : 0); + if (!len) return 1; + } +} diff --git a/libgnucash/core-utils/gnc-glib-utils.h b/libgnucash/core-utils/gnc-glib-utils.h index 97e36c53d4..c1a9a37b30 100644 --- a/libgnucash/core-utils/gnc-glib-utils.h +++ b/libgnucash/core-utils/gnc-glib-utils.h @@ -199,6 +199,20 @@ void gnc_scm_log_debug(const gchar *msg); **/ gchar * gnc_g_list_stringjoin (GList *list_of_strings, const gchar *sep); +/** + * @brief Scans the GList elements the minimum number of iterations + * required to test it against a specified size. Returns -1, 0 or 1 + * depending on whether the GList length has less, same, or more + * elements than the size specified. + * + * @param lst A GList + * + * @param len the comparator length to compare the GList length with + * + * @return A signed int comparing GList length with specified size. + **/ +gint gnc_list_length_cmp (const GList *list, size_t len); + /** Kill a process. On UNIX send a SIGKILL, on Windows call TerminateProcess. * * @param pid The process ID. */ diff --git a/libgnucash/core-utils/test/test-gnc-glib-utils.c b/libgnucash/core-utils/test/test-gnc-glib-utils.c index e4423baaac..0c59356e30 100644 --- a/libgnucash/core-utils/test/test-gnc-glib-utils.c +++ b/libgnucash/core-utils/test/test-gnc-glib-utils.c @@ -110,6 +110,28 @@ test_g_list_stringjoin (gconstpointer data) g_list_free (test); } +static void +test_gnc_list_length (gconstpointer data) +{ + GList *lst = NULL; + + g_assert (gnc_list_length_cmp (lst, 0) == 0); + g_assert (gnc_list_length_cmp (lst, 1) == -1); + + lst = g_list_prepend (lst, (gpointer)1); + g_assert (gnc_list_length_cmp (lst, 0) == 1); + g_assert (gnc_list_length_cmp (lst, 1) == 0); + g_assert (gnc_list_length_cmp (lst, 2) == -1); + + lst = g_list_prepend (lst, (gpointer)2); + g_assert (gnc_list_length_cmp (lst, 1) == 1); + g_assert (gnc_list_length_cmp (lst, 2) == 0); + g_assert (gnc_list_length_cmp (lst, 3) == -1); + + g_list_free (lst); +} + + int main (int argc, char *argv[]) { @@ -119,6 +141,7 @@ main (int argc, char *argv[]) g_test_add_data_func ("/core-utils/gnc_utf8_strip_invalid_and_controls invalid utf8", (gconstpointer)invalid_utf8, test_gnc_utf8_strip_invalid_and_controls); g_test_add_data_func ("/core-utils/gnc_utf8_strip_invalid_and_controls control chars", (gconstpointer)controls, test_gnc_utf8_strip_invalid_and_controls); g_test_add_data_func ("/core-utils/gnc_g_list_stringjoin", NULL, test_g_list_stringjoin); + g_test_add_data_func ("/core-utils/gnc_list_length", NULL, test_gnc_list_length); return g_test_run(); } diff --git a/libgnucash/engine/Recurrence.c b/libgnucash/engine/Recurrence.c index 9e2e33e8f5..b450e93689 100644 --- a/libgnucash/engine/Recurrence.c +++ b/libgnucash/engine/Recurrence.c @@ -31,8 +31,7 @@ #include "gnc-date.h" #include "Account.h" #include -#include -#include +#include #define LOG_MOD "gnc.engine.recurrence" static QofLogModule log_module = LOG_MOD; @@ -556,7 +555,7 @@ recurrenceWeekendAdjustFromString(const gchar *str) gboolean recurrenceListIsSemiMonthly(GList *recurrences) { - if (!(recurrences && recurrences->next && !recurrences->next->next)) + if (gnc_list_length_cmp (recurrences, 2)) return FALSE; // should be a "semi-monthly": diff --git a/libgnucash/engine/gncIDSearch.c b/libgnucash/engine/gncIDSearch.c index 449732c87d..921708d1d4 100644 --- a/libgnucash/engine/gncIDSearch.c +++ b/libgnucash/engine/gncIDSearch.c @@ -22,6 +22,7 @@ **********************************************************************/ #include "gncIDSearch.h" +#include typedef enum { UNDEFINED, @@ -122,7 +123,7 @@ static void * search(QofBook * book, const gchar *id, void * object, GncSearchTy result = qof_query_run (q); // now compare _exactly_ - if (result != NULL) + if (gnc_list_length_cmp (result, 0)) { result = g_list_first (result);