From 8418c91170bbef03851b31ab80db791d0c9829f6 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Wed, 9 Oct 2013 05:28:15 +0000 Subject: [PATCH] Adjust error-message tests to pass with Clang Clang emits full function signatures for __func__ where GCC emits only the function name. Adjust Gnucash's own error messages emitted via PWARN and friends to trim the extra bits so that only the function name is emitted regardless of compiler. For messages emitted directly by glib (usually from g_return_if_fail macros), the message in the test case is special-cased for Clang so that it matches and the test passes. git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@23289 57a11ea4-9604-0410-9ed3-97b8803252fd --- src/engine/test/test-object.c | 11 -------- src/engine/test/utest-Account.c | 44 ++++++++++++++++++++++++----- src/engine/test/utest-Split.c | 8 +++++- src/engine/test/utest-Transaction.c | 16 +++++++++-- src/libqof/qof/qofbook.c | 6 ++-- src/libqof/qof/qoflog.c | 30 ++++++++++++-------- src/libqof/qof/test/test-gnc-date.c | 24 ++++++++++++++-- src/libqof/qof/test/test-qofbook.c | 15 +++++++--- 8 files changed, 111 insertions(+), 43 deletions(-) diff --git a/src/engine/test/test-object.c b/src/engine/test/test-object.c index 7de3e3df26..c3edc1b8cd 100644 --- a/src/engine/test/test-object.c +++ b/src/engine/test/test-object.c @@ -40,27 +40,16 @@ static void test_foreach (QofBook *, const char *); static QofObject bus_obj = { -interface_version: QOF_OBJECT_VERSION, -e_type: TEST_MODULE_NAME, -type_label: TEST_MODULE_DESC, -create: NULL, -book_begin: NULL, -book_end: NULL, -is_dirty: NULL, -mark_clean: NULL, -foreach: obj_foreach, -printable: printable, -version_cmp: NULL, }; diff --git a/src/engine/test/utest-Account.c b/src/engine/test/utest-Account.c index 45ab17664b..4c06c8e096 100644 --- a/src/engine/test/utest-Account.c +++ b/src/engine/test/utest-Account.c @@ -462,7 +462,13 @@ test_gnc_account_list_name_violations (Fixture *fixture, gconstpointer pData) { guint log_level = G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL; gchar *log_domain = "gnc.engine"; - gchar *msg = "gnc_account_list_name_violations: assertion " _Q "separator != NULL' failed"; +#ifdef __clang__ +#define _func "GList *gnc_account_list_name_violations(QofBook *, const gchar *)" +#else +#define _func "gnc_account_list_name_violations" +#endif + gchar *msg = _func ": assertion " _Q "separator != NULL' failed"; +#undef _func TestErrorStruct check = { log_level, log_domain, msg, 0 }; GList *results, *res_iter; gchar *sep = ":"; @@ -743,8 +749,14 @@ test_xaccCloneAccount (Fixture *fixture, gconstpointer pData) Account *clone; QofBook *book = gnc_account_get_book (fixture->acct); guint loglevel = G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL; - gchar *msg1 = "xaccCloneAccount: assertion " _Q "GNC_IS_ACCOUNT(from)' failed"; - gchar *msg2 = "xaccCloneAccount: assertion " _Q "QOF_IS_BOOK(book)' failed"; +#ifdef __clang__ +#define _func "Account *xaccCloneAccount(const Account *, QofBook *)" +#else +#define _func "xaccCloneAccount" +#endif + gchar *msg1 = _func ": assertion " _Q "GNC_IS_ACCOUNT(from)' failed"; + gchar *msg2 = _func ": assertion " _Q "QOF_IS_BOOK(book)' failed"; +#undef _func TestErrorStruct check = { loglevel, "gnc.engine", msg1, 0 }; GLogFunc oldlogger; AccountPrivate *acct_p, *clone_p; @@ -840,7 +852,13 @@ test_xaccFreeAccount (Fixture *fixture, gconstpointer pData) { gchar *msg1 = "[xaccFreeAccount()] instead of calling xaccFreeAccount(), please call \n" " xaccAccountBeginEdit(); xaccAccountDestroy(); \n"; - gchar *msg2 = "xaccTransGetSplitIndex: assertion " _Q "trans && split' failed"; +#ifdef __clang__ +#define _func "int xaccTransGetSplitIndex(const Transaction *, const Split *)" +#else +#define _func "xaccTransGetSplitIndex" +#endif + gchar *msg2 = _func ": assertion " _Q "trans && split' failed"; +#undef _func guint loglevel = G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL; TestErrorStruct check1 = { loglevel, "gnc.account", msg1, 0 }; TestErrorStruct check2 = { loglevel, "gnc.engine", msg2, 0 }; @@ -948,7 +966,13 @@ test_xaccAccountCommitEdit (Fixture *fixture, gconstpointer pData) { gchar *msg1 = "[xaccFreeAccount()] instead of calling xaccFreeAccount(), please call \n" " xaccAccountBeginEdit(); xaccAccountDestroy(); \n"; - gchar *msg2 = "xaccTransGetSplitIndex: assertion " _Q "trans && split' failed"; +#ifdef __clang__ +#define _func "int xaccTransGetSplitIndex(const Transaction *, const Split *)" +#else +#define _func "xaccTransGetSplitIndex" +#endif + gchar *msg2 = _func ": assertion " _Q "trans && split' failed"; +#undef _func guint loglevel = G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL; TestErrorStruct check1 = { loglevel, "gnc.account", msg1, 0 }; TestErrorStruct check2 = { loglevel, "gnc.engine", msg2, 0 }; @@ -1059,8 +1083,14 @@ test_gnc_account_insert_remove_split (Fixture *fixture, gconstpointer pData) Split *split3 = xaccMallocSplit (book); TestSignal sig1, sig2, sig3; AccountPrivate *priv = fixture->func->get_private (fixture->acct); - gchar *msg1 = "gnc_account_insert_split: assertion " _Q "GNC_IS_ACCOUNT(acc)' failed"; - gchar *msg2 = "gnc_account_insert_split: assertion " _Q "GNC_IS_SPLIT(s)' failed"; +#ifdef __clang__ +#define _func "gboolean gnc_account_insert_split(Account *, Split *)" +#else +#define _func "gnc_account_insert_split" +#endif + gchar *msg1 = _func ": assertion " _Q "GNC_IS_ACCOUNT(acc)' failed"; + gchar *msg2 = _func ": assertion " _Q "GNC_IS_SPLIT(s)' failed"; +#undef _func guint loglevel = G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL; // gchar *log_domain = "gnc.engine"; TestErrorStruct check1 = { loglevel, "gnc.engine", msg1, 0 }; diff --git a/src/engine/test/utest-Split.c b/src/engine/test/utest-Split.c index 89958f244f..caf35e974c 100644 --- a/src/engine/test/utest-Split.c +++ b/src/engine/test/utest-Split.c @@ -1268,7 +1268,13 @@ test_get_corr_account_split (Fixture *fixture, gconstpointer pData) Account *acc1 = xaccMallocAccount (book); Account *acc2 = xaccMallocAccount (book); Account *acc3 = xaccMallocAccount (book); - gchar *msg = "get_corr_account_split: assertion " _Q "sa' failed"; +#ifdef __clang__ +#define _func "gboolean get_corr_account_split(const Split *, const Split **)" +#else +#define _func "get_corr_account_split" +#endif + gchar *msg = _func ": assertion " _Q "sa' failed"; +#undef _func guint loglevel = G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL; TestErrorStruct *check = test_error_struct_new ("gnc.engine", loglevel, msg); diff --git a/src/engine/test/utest-Transaction.c b/src/engine/test/utest-Transaction.c index ffef500f19..4faf0362b1 100644 --- a/src/engine/test/utest-Transaction.c +++ b/src/engine/test/utest-Transaction.c @@ -486,7 +486,13 @@ test_xaccMallocTransaction (Fixture *fixture, gconstpointer pData) QofBook *book = qof_book_new (); TestSignal sig1 = test_signal_new (NULL, QOF_EVENT_CREATE,NULL); Transaction *txn; - gchar *msg = "xaccMallocTransaction: assertion " _Q "book' failed"; +#ifdef __clang__ +#define _func "Transaction *xaccMallocTransaction(QofBook *)" +#else +#define _func "xaccMallocTransaction" +#endif + gchar *msg = _func ": assertion " _Q "book' failed"; +#undef _func gchar *logdomain = "gnc.engine"; guint loglevel = G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL; TestErrorStruct *check = test_error_struct_new ("gnc.engine", loglevel, @@ -1265,7 +1271,13 @@ xaccTransGetAccountBalance (const Transaction *trans,// C: 1 Local: 0:0:0 static void test_xaccTransGetAccountBalance (Fixture *fixture, gconstpointer pData) { - gchar *msg1 = "xaccTransGetAccountBalance: assertion " _Q "account && trans' failed"; +#ifdef __clang__ +#define _func "gnc_numeric xaccTransGetAccountBalance(const Transaction *, const Account *)" +#else +#define _func "xaccTransGetAccountBalance" +#endif + gchar *msg1 = _func ": assertion " _Q "account && trans' failed"; +#undef _func guint loglevel = G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL; TestErrorStruct *check = test_error_struct_new ("gnc.engine", loglevel, msg1); diff --git a/src/libqof/qof/qofbook.c b/src/libqof/qof/qofbook.c index bbf8008d94..e2b6aa24b4 100644 --- a/src/libqof/qof/qofbook.c +++ b/src/libqof/qof/qofbook.c @@ -194,7 +194,7 @@ void qof_book_print_dirty (const QofBook *book) { if (qof_book_session_not_saved(book)) - printf("book is dirty.\n"); + PINFO("book is dirty."); qof_book_foreach_collection (book, (QofCollectionForeachCB)qof_collection_print_dirty, NULL); } @@ -209,7 +209,7 @@ void qof_book_set_dirty_cb(QofBook *book, QofBookDirtyCB cb, gpointer user_data) { if (book->dirty_cb) - g_warning("qof_book_set_dirty_cb: Already existing callback %p, will be overwritten by %p\n", + PWARN("Already existing callback %p, will be overwritten by %p\n", book->dirty_cb, cb); book->dirty_data = user_data; book->dirty_cb = cb; @@ -692,7 +692,7 @@ gint qof_book_get_num_days_autoreadonly (const QofBook *book) if (kvp_val == NULL) { - //g_warning("kvp_val for slot '%s' is NULL", OPTION_NAME_AUTO_READONLY_DAYS); + //PWARN("kvp_val for slot '%s' is NULL", OPTION_NAME_AUTO_READONLY_DAYS); return 0; } diff --git a/src/libqof/qof/qoflog.c b/src/libqof/qof/qoflog.c index e55bb37aad..bb04b48a84 100644 --- a/src/libqof/qof/qoflog.c +++ b/src/libqof/qof/qoflog.c @@ -51,6 +51,7 @@ #include "qoflog.h" #define QOF_LOG_MAX_CHARS 50 +#define QOF_LOG_MAX_CHARS_WITH_ALLOWANCE 100 #define QOF_LOG_INDENT_WIDTH 4 #define NUM_CLOCKS 10 @@ -238,28 +239,33 @@ qof_log_set_level(QofLogModule log_module, QofLogLevel level) const char * qof_log_prettify (const char *name) { - gchar *p, *buffer; + gchar *p, *buffer, *begin; gint length; if (!name) { return ""; } - buffer = g_strndup(name, QOF_LOG_MAX_CHARS - 1); +/* Clang's __func__ displays the whole signature, like a good C++ + * compier should. Gcc displays only the name of the function. Strip + * the extras from Clang's output so that log messages are the same + * regardless of compiler. + */ + buffer = g_strndup(name, QOF_LOG_MAX_CHARS_WITH_ALLOWANCE - 1); length = strlen(buffer); - p = g_strstr_len(buffer, length, "("); - if (p) - { - *(p + 1) = ')'; - *(p + 2) = 0x0; - } + p = g_strstr_len (buffer, length, "("); + if (p) *p = '\0'; + begin = g_strrstr (buffer, "*"); + if (begin == NULL) + begin = g_strrstr (buffer, " "); + if (begin != NULL) + p = begin + 1; else - { - strcpy (&buffer[QOF_LOG_MAX_CHARS - 6], "...()"); - } + p = buffer; + if (function_buffer) g_free(function_buffer); - function_buffer = g_strdup(buffer); + function_buffer = g_strdup(p); g_free(buffer); return function_buffer; } diff --git a/src/libqof/qof/test/test-gnc-date.c b/src/libqof/qof/test/test-gnc-date.c index 791493e1e5..6db675d83f 100644 --- a/src/libqof/qof/test/test-gnc-date.c +++ b/src/libqof/qof/test/test-gnc-date.c @@ -69,7 +69,13 @@ test_gnc_localtime (void) // difference between g_date_time and tm->tm_wday) }; guint ind; - gchar *msg = "gnc_localtime_r: assertion " _Q "gdt != NULL' failed"; +#ifdef __clang__ +#define _func "struct tm *gnc_localtime_r(const time64 *, struct tm *)" +#else +#define _func "gnc_localtime_r" +#endif + gchar *msg = _func ": assertion " _Q "gdt != NULL' failed"; +#undef _func gint loglevel = G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL; gchar *logdomain = "qof"; TestErrorStruct check = {loglevel, logdomain, msg, 0}; @@ -132,7 +138,13 @@ test_gnc_gmtime (void) #endif }; guint ind; - gchar *msg = "gnc_gmtime: assertion " _Q "gdt != NULL' failed"; +#ifdef __clang__ +#define _func "struct tm *gnc_gmtime(const time64 *)" +#else +#define _func "gnc_gmtime" +#endif + gchar *msg = _func ": assertion " _Q "gdt != NULL' failed"; +#undef _func gint loglevel = G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL; gchar *logdomain = "qof"; TestErrorStruct check = {loglevel, logdomain, msg, 0}; @@ -1695,7 +1707,13 @@ test_gnc_timespec_to_iso8601_buff (void) gchar *end; gchar *logdomain = "qof"; guint loglevel = G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL; - gchar *msg = "gnc_timespec_to_iso8601_buff: assertion " _Q "buff != NULL' failed"; +#ifdef __clang__ +#define _func "gchar *gnc_timespec_to_iso8601_buff(Timespec, char *)" +#else +#define _func "gnc_timespec_to_iso8601_buff" +#endif + gchar *msg = _func ": assertion " _Q "buff != NULL' failed"; +#undef _func TestErrorStruct check = { loglevel, logdomain, msg, 0 }; GLogFunc oldlogger = g_log_set_default_handler ((GLogFunc)test_null_handler, &check); diff --git a/src/libqof/qof/test/test-qofbook.c b/src/libqof/qof/test/test-qofbook.c index a42a5da57b..b8377644d4 100644 --- a/src/libqof/qof/test/test-qofbook.c +++ b/src/libqof/qof/test/test-qofbook.c @@ -610,8 +610,15 @@ test_book_foreach_collection( Fixture *fixture, gconstpointer pData ) G_GNUC_UNUSED QofCollection *m_col, *m_col2; QofIdType my_type = "my_type", my_type2 = "my_type2"; guint param = (guint) g_test_rand_int(); - gchar *msg1 = "qof_book_foreach_collection: assertion " _Q "book' failed"; - gchar *msg2 = "qof_book_foreach_collection: assertion " _Q "cb' failed"; +/* GLib assertion messages which aren't filtered to make clang's output like gcc's */ +#ifdef __clang__ +#define _func "void qof_book_foreach_collection(const QofBook *, QofCollectionForeachCB, gpointer)" +#else +#define _func "qof_book_foreach_collection" +#endif + gchar *msg1 = _func ": assertion " _Q "book' failed"; + gchar *msg2 = _func ": assertion " _Q "cb' failed"; +#undef _func gchar *log_domain = "qof"; guint loglevel = G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL, hdlr; TestErrorStruct check1 = { loglevel, log_domain, msg1 }; @@ -634,7 +641,7 @@ test_book_foreach_collection( Fixture *fixture, gconstpointer pData ) qof_book_foreach_collection( NULL, mock_foreach_collection, (gpointer)(¶m) ); g_assert( !col_struct.col1_called ); g_assert( !col_struct.col2_called ); - g_assert_cmpstr( test_struct.msg, == , "qof_book_foreach_collection: assertion " _Q "book' failed" ); + g_assert_cmpstr( test_struct.msg, == , msg1); g_free( test_struct.msg ); g_test_message( "Testing when cb is null" ); @@ -642,7 +649,7 @@ test_book_foreach_collection( Fixture *fixture, gconstpointer pData ) qof_book_foreach_collection( fixture->book, NULL, (gpointer)(¶m) ); g_assert( !col_struct.col1_called ); g_assert( !col_struct.col2_called ); - g_assert_cmpstr( test_struct.msg, == , "qof_book_foreach_collection: assertion " _Q "cb' failed" ); + g_assert_cmpstr( test_struct.msg, == , msg2); g_free( test_struct.msg ); g_log_remove_handler (log_domain, hdlr); test_clear_error_list ();