diff --git a/src/app-utils/gnc-component-manager.c b/src/app-utils/gnc-component-manager.c index 9a47f6d475..030eb9ca00 100644 --- a/src/app-utils/gnc-component-manager.c +++ b/src/app-utils/gnc-component-manager.c @@ -260,8 +260,10 @@ gnc_cm_event_handler (QofInstance *entity, { const GncGUID *guid = qof_entity_get_guid(entity); #if CM_DEBUG + gchar guidstr[GUID_ENCODING_LENGTH+1]; + guid_to_string_buff (guid, guidstr); fprintf (stderr, "event_handler: event %d, entity %p, guid %s\n", event_type, - entity, guid_to_string(guid)); + entity, guidstr); #endif add_event (&changes, guid, event_type, TRUE); diff --git a/src/app-utils/gnc-state.c b/src/app-utils/gnc-state.c index 2896717acb..801f311f33 100644 --- a/src/app-utils/gnc-state.c +++ b/src/app-utils/gnc-state.c @@ -71,7 +71,8 @@ gnc_state_set_base (const QofSession *session) { gchar *basename, *original = NULL, *filename, *file_guid; gchar *sf_extension = NULL, *newstyle_filename = NULL; - const gchar *uri, *guid_string; + const gchar *uri; + gchar guid_string[GUID_ENCODING_LENGTH+1]; QofBook *book; const GncGUID *guid; GKeyFile *key_file = NULL; @@ -94,7 +95,7 @@ gnc_state_set_base (const QofSession *session) /* Get the book GncGUID */ book = qof_session_get_book(session); guid = qof_entity_get_guid(QOF_INSTANCE(book)); - guid_string = guid_to_string(guid); + guid_to_string_buff(guid, guid_string); if (gnc_uri_is_file_uri (uri)) { diff --git a/src/app-utils/gnc-sx-instance-model.c b/src/app-utils/gnc-sx-instance-model.c index bfe2701ff6..119c8faec6 100644 --- a/src/app-utils/gnc-sx-instance-model.c +++ b/src/app-utils/gnc-sx-instance-model.c @@ -1490,6 +1490,8 @@ static void add_to_hash_amount(GHashTable* hash, const GncGUID* guid, const gnc_ * modify it in-place; if not, insert the new element into the * hash. */ gnc_numeric* elem = g_hash_table_lookup(hash, guid); + gchar guidstr[GUID_ENCODING_LENGTH+1]; + guid_to_string_buff(guid, guidstr); if (!elem) { elem = g_new0(gnc_numeric, 1); @@ -1503,7 +1505,7 @@ static void add_to_hash_amount(GHashTable* hash, const GncGUID* guid, const gnc_ g_critical("Oops, the given amount [%s] has the error code %d, at guid [%s].", gnc_num_dbg_to_string(*amount), gnc_numeric_check(*amount), - guid_to_string(guid)); + guidstr); return; } if (gnc_numeric_check(*elem) != GNC_ERROR_OK) @@ -1511,7 +1513,7 @@ static void add_to_hash_amount(GHashTable* hash, const GncGUID* guid, const gnc_ g_critical("Oops, the account's amount [%s] has the error code %d, at guid [%s].", gnc_num_dbg_to_string(*elem), gnc_numeric_check(*elem), - guid_to_string(guid)); + guidstr); return; } @@ -1527,7 +1529,7 @@ static void add_to_hash_amount(GHashTable* hash, const GncGUID* guid, const gnc_ if (gnc_numeric_check(*elem) != GNC_ERROR_OK) { g_critical("Oops, after addition at guid [%s] the resulting amount [%s] has the error code %d; added amount = [%s].", - guid_to_string(guid), + guidstr, gnc_num_dbg_to_string(*elem), gnc_numeric_check(*elem), gnc_num_dbg_to_string(*amount)); @@ -1536,7 +1538,7 @@ static void add_to_hash_amount(GHashTable* hash, const GncGUID* guid, const gnc_ /* In case anyone wants to see this in the debug log. */ g_debug("Adding to guid [%s] the value [%s]. Value now [%s].", - guid_to_string(guid), + guidstr, gnc_num_dbg_to_string(*amount), gnc_num_dbg_to_string(*elem)); } diff --git a/src/app-utils/guile-util.c b/src/app-utils/guile-util.c index 52307370db..dab9e3bd79 100644 --- a/src/app-utils/guile-util.c +++ b/src/app-utils/guile-util.c @@ -297,7 +297,7 @@ gnc_is_trans_scm(SCM scm) void gnc_split_scm_set_account(SCM split_scm, Account *account) { - const char *guid_string; + gchar guid_string[GUID_ENCODING_LENGTH+1]; SCM arg; initialize_scm_functions(); @@ -307,7 +307,7 @@ gnc_split_scm_set_account(SCM split_scm, Account *account) if (account == NULL) return; - guid_string = guid_to_string(xaccAccountGetGUID(account)); + guid_to_string_buff(xaccAccountGetGUID(account), guid_string); if (guid_string == NULL) return; @@ -657,6 +657,7 @@ gnc_copy_trans_scm_onto_trans_swap_accounts(SCM trans_scm, } else { + gchar guidstr[GUID_ENCODING_LENGTH+1]; SCM from, to; SCM map = SCM_EOL; SCM args = SCM_EOL; @@ -668,8 +669,10 @@ gnc_copy_trans_scm_onto_trans_swap_accounts(SCM trans_scm, args = scm_cons(commit, args); - from = scm_from_utf8_string(guid_to_string(guid_1)); - to = scm_from_utf8_string(guid_to_string(guid_2)); + guid_to_string_buff(guid_1, guidstr); + from = scm_from_utf8_string(guidstr); + guid_to_string_buff(guid_2, guidstr); + to = scm_from_utf8_string(guidstr); map = scm_cons(scm_cons(from, to), map); map = scm_cons(scm_cons(to, from), map); diff --git a/src/app-utils/test/test-scm-query-string.c b/src/app-utils/test/test-scm-query-string.c index bb4119196a..448f0e47f6 100644 --- a/src/app-utils/test/test-scm-query-string.c +++ b/src/app-utils/test/test-scm-query-string.c @@ -103,7 +103,6 @@ main_helper (void *closure, int argc, char **argv) kvp_exclude_type (KVP_TYPE_DOUBLE); /* Initialize to a known RNG position */ - guid_init(); srand(1); run_tests (); diff --git a/src/backend/sql/gnc-transaction-sql.c b/src/backend/sql/gnc-transaction-sql.c index 46fc3d9790..f48ce71d35 100644 --- a/src/backend/sql/gnc-transaction-sql.c +++ b/src/backend/sql/gnc-transaction-sql.c @@ -225,10 +225,11 @@ load_single_split( GncSqlBackend* be, GncSqlRow* row ) /*# -ifempty */ if (pSplit != xaccSplitLookup( &split_guid, be->book )) { - PERR("A malformed split with id %s was found in the dataset.", - guid_to_string(qof_instance_get_guid(pSplit))); - qof_backend_set_error( &be->be, ERR_BACKEND_DATA_CORRUPT); - pSplit = NULL; + gchar guidstr[GUID_ENCODING_LENGTH+1]; + guid_to_string_buff(qof_instance_get_guid(pSplit), guidstr); + PERR("A malformed split with id %s was found in the dataset.", guidstr); + qof_backend_set_error( &be->be, ERR_BACKEND_DATA_CORRUPT); + pSplit = NULL; } return pSplit; } @@ -305,10 +306,11 @@ load_single_tx( GncSqlBackend* be, GncSqlRow* row ) if (pTx != xaccTransLookup( &tx_guid, be->book )) { - PERR("A malformed transaction with id %s was found in the dataset.", - guid_to_string(qof_instance_get_guid(pTx))); - qof_backend_set_error( &be->be, ERR_BACKEND_DATA_CORRUPT); - pTx = NULL; + gchar guidstr[GUID_ENCODING_LENGTH+1]; + guid_to_string_buff(qof_instance_get_guid(pTx), guidstr); + PERR("A malformed transaction with id %s was found in the dataset.", guidstr); + qof_backend_set_error( &be->be, ERR_BACKEND_DATA_CORRUPT); + pTx = NULL; } return pTx; diff --git a/src/backend/xml/gnc-bill-term-xml-v2.c b/src/backend/xml/gnc-bill-term-xml-v2.c index f5d6b53fe0..fa4d421a47 100644 --- a/src/backend/xml/gnc-bill-term-xml-v2.c +++ b/src/backend/xml/gnc-bill-term-xml-v2.c @@ -588,8 +588,9 @@ billterm_scrub_cb (QofInstance *term_p, gpointer list_p) if (t) { /* Fix up the broken "copy" function */ - PWARN("Fixing broken child billterm: %s", - guid_to_string(qof_instance_get_guid(QOF_INSTANCE(term)))); + gchar guidstr[GUID_ENCODING_LENGTH+1]; + guid_to_string_buff(qof_instance_get_guid(QOF_INSTANCE(term)),guidstr); + PWARN("Fixing broken child billterm: %s", guidstr); gncBillTermBeginEdit(term); gncBillTermSetType(term, gncBillTermGetType(t)); @@ -624,8 +625,9 @@ billterm_scrub_invoices (QofInstance * invoice_p, gpointer ht_p) { if (billterm_is_grandchild(term)) { - PWARN("Fixing i-billterm on invoice %s\n", - guid_to_string(qof_instance_get_guid(QOF_INSTANCE(invoice)))); + gchar guidstr[GUID_ENCODING_LENGTH+1]; + guid_to_string_buff(qof_instance_get_guid(QOF_INSTANCE(invoice)),guidstr); + PWARN("Fixing i-billterm on invoice %s\n", guidstr); new_bt = billterm_find_senior(term); gncInvoiceBeginEdit(invoice); gncInvoiceSetTerms(invoice, new_bt); @@ -656,9 +658,13 @@ billterm_scrub_cust (QofInstance * cust_p, gpointer ht_p) count++; g_hash_table_insert(ht, term, GINT_TO_POINTER(count)); if (billterm_is_grandchild(term)) - PWARN("customer %s has grandchild billterm %s\n", - guid_to_string(qof_instance_get_guid(QOF_INSTANCE(cust))), - guid_to_string(qof_instance_get_guid(QOF_INSTANCE(term)))); + { + gchar custstr[GUID_ENCODING_LENGTH+1]; + gchar termstr[GUID_ENCODING_LENGTH+1]; + guid_to_string_buff(qof_instance_get_guid(QOF_INSTANCE(cust)),custstr); + guid_to_string_buff(qof_instance_get_guid(QOF_INSTANCE(term)),termstr); + PWARN("customer %s has grandchild billterm %s\n", custstr,termstr); + } } } @@ -677,9 +683,13 @@ billterm_scrub_vendor (QofInstance * vendor_p, gpointer ht_p) count++; g_hash_table_insert(ht, term, GINT_TO_POINTER(count)); if (billterm_is_grandchild(term)) - PWARN("vendor %s has grandchild billterm %s\n", - guid_to_string(qof_instance_get_guid(QOF_INSTANCE(vendor))), - guid_to_string(qof_instance_get_guid(QOF_INSTANCE(term)))); + { + gchar vendstr[GUID_ENCODING_LENGTH+1]; + gchar termstr[GUID_ENCODING_LENGTH+1]; + guid_to_string_buff(qof_instance_get_guid(QOF_INSTANCE(vendor)),vendstr); + guid_to_string_buff(qof_instance_get_guid(QOF_INSTANCE(term)),termstr); + PWARN("vendor %s has grandchild billterm %s\n", vendstr, termstr); + } } } @@ -691,9 +701,10 @@ billterm_reset_refcount (gpointer key, gpointer value, gpointer notused) if (count != gncBillTermGetRefcount(term) && !gncBillTermGetInvisible(term)) { + gchar termstr[GUID_ENCODING_LENGTH+1]; + guid_to_string_buff(qof_instance_get_guid(QOF_INSTANCE(term)),termstr); PWARN("Fixing refcount on billterm %s (%" G_GINT64_FORMAT " -> %d)\n", - guid_to_string(qof_instance_get_guid(QOF_INSTANCE(term))), - gncBillTermGetRefcount(term), count); + termstr, gncBillTermGetRefcount(term), count); gncBillTermSetRefcount(term, count); } } @@ -715,10 +726,11 @@ billterm_scrub (QofBook *book) /* destroy the list of "grandchildren" bill terms */ for (node = list; node; node = node->next) { + gchar termstr[GUID_ENCODING_LENGTH+1]; term = node->data; - PWARN ("deleting grandchild billterm: %s\n", - guid_to_string(qof_instance_get_guid(QOF_INSTANCE(term)))); + guid_to_string_buff(qof_instance_get_guid(QOF_INSTANCE(term)), termstr); + PWARN ("deleting grandchild billterm: %s\n", termstr); /* Make sure the parent has no children */ parent = gncBillTermGetParent(term); @@ -770,11 +782,13 @@ GncBillTerm * gnc_billterm_xml_find_or_create(QofBook *book, GncGUID *guid) { GncBillTerm *term; + gchar guidstr[GUID_ENCODING_LENGTH+1]; + guid_to_string_buff(guid, guidstr); g_return_val_if_fail(book, NULL); g_return_val_if_fail(guid, NULL); term = gncBillTermLookup(book, guid); - DEBUG("looking for billterm %s, found %p", guid_to_string(guid), term); + DEBUG("looking for billterm %s, found %p", guidstr, term); if (!term) { term = gncBillTermCreate(book); diff --git a/src/backend/xml/gnc-schedxaction-xml-v2.c b/src/backend/xml/gnc-schedxaction-xml-v2.c index b6045560fa..2fd90caaa7 100644 --- a/src/backend/xml/gnc-schedxaction-xml-v2.c +++ b/src/backend/xml/gnc-schedxaction-xml-v2.c @@ -740,10 +740,10 @@ gnc_schedXaction_end_handler(gpointer data_for_children, if ( sx->template_acct == NULL ) { Account *ra = NULL; - const char *id = NULL; Account *acct = NULL; sixtp_gdv2 *sixdata = gdata->parsedata; QofBook *book; + gchar guidstr[GUID_ENCODING_LENGTH+1]; book = sixdata->book; @@ -751,8 +751,7 @@ gnc_schedXaction_end_handler(gpointer data_for_children, change re: storing template accounts. */ /* Fix: get account with name of our GncGUID from the template accounts. Make that our template_acct pointer. */ - /* THREAD-UNSAFE */ - id = guid_to_string( xaccSchedXactionGetGUID( sx ) ); + guid_to_string_buff( xaccSchedXactionGetGUID( sx ), guidstr ); ra = gnc_book_get_template_root(book); if ( ra == NULL ) { @@ -760,15 +759,15 @@ gnc_schedXaction_end_handler(gpointer data_for_children, xmlFreeNode( tree ); return FALSE; } - acct = gnc_account_lookup_by_name( ra, id ); + acct = gnc_account_lookup_by_name( ra, guidstr ); if ( acct == NULL ) { - g_warning("no template account with name [%s]", id); + g_warning("no template account with name [%s]", guidstr); xmlFreeNode( tree ); return FALSE; } g_debug("template account name [%s] for SX with GncGUID [%s]", - xaccAccountGetName( acct ), id ); + xaccAccountGetName( acct ), guidstr ); /* FIXME: free existing template account. * HUH????? We only execute this if there isn't diff --git a/src/backend/xml/gnc-tax-table-xml-v2.c b/src/backend/xml/gnc-tax-table-xml-v2.c index 0990e4b651..e427a2bfc9 100644 --- a/src/backend/xml/gnc-tax-table-xml-v2.c +++ b/src/backend/xml/gnc-tax-table-xml-v2.c @@ -576,8 +576,9 @@ taxtable_scrub_entries (QofInstance * entry_p, gpointer ht_p) { if (taxtable_is_grandchild(table)) { - PINFO("Fixing i-taxtable on entry %s\n", - guid_to_string(qof_instance_get_guid(QOF_INSTANCE(entry)))); + gchar guidstr[GUID_ENCODING_LENGTH+1]; + guid_to_string_buff(qof_instance_get_guid(QOF_INSTANCE(entry)),guidstr); + PINFO("Fixing i-taxtable on entry %s\n",guidstr); new_tt = taxtable_find_senior(table); gncEntryBeginEdit(entry); gncEntrySetInvTaxTable(entry, new_tt); @@ -597,8 +598,9 @@ taxtable_scrub_entries (QofInstance * entry_p, gpointer ht_p) { if (taxtable_is_grandchild(table)) { - PINFO("Fixing b-taxtable on entry %s\n", - guid_to_string(qof_instance_get_guid(QOF_INSTANCE(entry)))); + gchar guidstr[GUID_ENCODING_LENGTH+1]; + guid_to_string_buff(qof_instance_get_guid(QOF_INSTANCE(entry)),guidstr); + PINFO("Fixing b-taxtable on entry %s\n",guidstr); new_tt = taxtable_find_senior(table); gncEntryBeginEdit(entry); gncEntrySetBillTaxTable(entry, new_tt); @@ -656,9 +658,10 @@ taxtable_reset_refcount (gpointer key, gpointer value, gpointer notused) if (count != gncTaxTableGetRefcount(table) && !gncTaxTableGetInvisible(table)) { + gchar guidstr[GUID_ENCODING_LENGTH+1]; + guid_to_string_buff(qof_instance_get_guid(QOF_INSTANCE(table)),guidstr); PWARN("Fixing refcount on taxtable %s (%" G_GINT64_FORMAT " -> %d)\n", - guid_to_string(qof_instance_get_guid(QOF_INSTANCE(table))), - gncTaxTableGetRefcount(table), count); + guidstr,gncTaxTableGetRefcount(table), count); gncTaxTableSetRefcount(table, count); } } @@ -679,10 +682,11 @@ taxtable_scrub (QofBook *book) /* destroy the list of "grandchildren" tax tables */ for (node = list; node; node = node->next) { + gchar guidstr[GUID_ENCODING_LENGTH+1]; table = node->data; - PINFO ("deleting grandchild taxtable: %s\n", - guid_to_string(qof_instance_get_guid(QOF_INSTANCE(table)))); + guid_to_string_buff(qof_instance_get_guid(QOF_INSTANCE(table)),guidstr); + PINFO ("deleting grandchild taxtable: %s\n", guidstr); /* Make sure the parent has no children */ parent = gncTaxTableGetParent(table); diff --git a/src/backend/xml/sixtp-dom-generators.c b/src/backend/xml/sixtp-dom-generators.c index 64ed084005..bb9c7ef20d 100644 --- a/src/backend/xml/sixtp-dom-generators.c +++ b/src/backend/xml/sixtp-dom-generators.c @@ -308,10 +308,12 @@ add_kvp_value_node(xmlNodePtr node, gchar *tag, kvp_value* val) xmlSetProp(val_node, BAD_CAST "type", BAD_CAST "string"); break; case KVP_TYPE_GUID: - /* THREAD-UNSAFE */ - add_text_to_node(val_node, "guid", - g_strdup(guid_to_string(kvp_value_get_guid(val)))); + { + gchar guidstr[GUID_ENCODING_LENGTH+1]; + guid_to_string_buff(kvp_value_get_guid(val), guidstr); + add_text_to_node(val_node, "guid", guidstr); break; + } case KVP_TYPE_TIMESPEC: { Timespec ts = kvp_value_get_timespec (val); diff --git a/src/backend/xml/test/test-xml-transaction.c b/src/backend/xml/test/test-xml-transaction.c index 14edc799a6..3d58da21ad 100644 --- a/src/backend/xml/test/test-xml-transaction.c +++ b/src/backend/xml/test/test-xml-transaction.c @@ -218,7 +218,9 @@ equals_node_val_vs_splits(xmlNodePtr node, const Transaction *trn) if (!spl_node) { - g_print( "Split GUID %s", guid_to_string(xaccSplitGetGUID(spl_mark)) ); + gchar guidstr[GUID_ENCODING_LENGTH+1]; + guid_to_string_buff(xaccSplitGetGUID(spl_mark),guidstr); + g_print( "Split GUID %s", guidstr ); return "no matching split found"; } diff --git a/src/business/business-gnome/dialog-invoice.c b/src/business/business-gnome/dialog-invoice.c index a759eedf9e..c4374918da 100644 --- a/src/business/business-gnome/dialog-invoice.c +++ b/src/business/business-gnome/dialog-invoice.c @@ -2177,24 +2177,25 @@ gnc_invoice_save_page (InvoiceWindow *iw, GKeyFile *key_file, const gchar *group_name) { + gchar guidstr[GUID_ENCODING_LENGTH+1]; + guid_to_string_buff(&iw->invoice_guid, guidstr); g_key_file_set_string(key_file, group_name, KEY_INVOICE_TYPE, InvoiceDialogTypeasString(iw->dialog_type)); - g_key_file_set_string(key_file, group_name, KEY_INVOICE_GUID, - guid_to_string(&iw->invoice_guid)); + g_key_file_set_string(key_file, group_name, KEY_INVOICE_GUID, guidstr); if (gncOwnerGetJob (&(iw->job))) { g_key_file_set_string(key_file, group_name, KEY_OWNER_TYPE, qofOwnerGetType(&iw->job)); - g_key_file_set_string(key_file, group_name, KEY_OWNER_GUID, - guid_to_string(gncOwnerGetGUID(&iw->job))); + guid_to_string_buff(gncOwnerGetGUID(&iw->job), guidstr); + g_key_file_set_string(key_file, group_name, KEY_OWNER_GUID, guidstr); } else { g_key_file_set_string(key_file, group_name, KEY_OWNER_TYPE, qofOwnerGetType(&iw->owner)); - g_key_file_set_string(key_file, group_name, KEY_OWNER_GUID, - guid_to_string(gncOwnerGetGUID(&iw->owner))); + guid_to_string_buff(gncOwnerGetGUID(&iw->owner), guidstr); + g_key_file_set_string(key_file, group_name, KEY_OWNER_GUID, guidstr); } } diff --git a/src/doc/design/engine.texi b/src/doc/design/engine.texi index a33c31c376..77097d31c3 100644 --- a/src/doc/design/engine.texi +++ b/src/doc/design/engine.texi @@ -287,12 +287,12 @@ Return the @code{memcmp} of the two GUID's. You can encode and decode GUIDs and their string representations using the next two functions. -@deftypefun {const char *} guid_to_string (const GUID * @var{guid}) +@deftypefun {gchar *} guid_to_string (const GUID * @var{guid}) Return a null-terminated string encoding of @var{guid}. String encodings of identifiers are hex numbers printed only with the characters @code{0} through @code{9} and @code{a} through @code{f}. The encoding will always be @code{GUID_ENCODING_LENGTH} characters long. The returned -string must NOT be freed when no longer needed. +string must be freed when no longer needed using g_free. @end deftypefun @deftypefun {char *} guid_to_string_buff (const GUID * @var{guid}, char * @var{buff}) @@ -353,7 +353,7 @@ entities such as Accounts and Transactions. Generate a new guid. This function is guaranteed to return a guid that is unique within the scope of all GnuCash entities being managed by the the current invocation of GnuCash. GnuCash routines should always use -this function and not @code{guid_new}! +this function and not @code{guid_replace}! @end deftypefun @deftypefun {void *} xaccLookupEntity (const GUID * @var{guid}, GNCIdType @var{entity_type}) @@ -378,23 +378,7 @@ entity is not changed in any way. GUIDs are created by the GUID generator. The API for this generator is low-level and should not be used by user-code. -@deftypefun void guid_init (void) -Initialize the GUID generator with a variety of random sources including -common system files and /dev/random. -@end deftypefun - -@deftypefun void guid_init_with_salt (const void * @var{salt}, size_t @var{salt_len}) -Initialize the GUID generator with guid_init() and with the given -sequence of arbitrary binary data. -@end deftypefun - -@deftypefun void guid_init_only_salt (const void * @var{salt}, size_t @var{salt_len}) -Initialize the GUID generator using only the given sequence of arbitrary -binary data. This provides a way to reliably obtain a given sequence of -GUIDs. -@end deftypefun - -@deftypefun void guid_new (GUID * @var{guid}) +@deftypefun void guid_replace (GUID * @var{guid}) Create a new GUID and store it in @var{guid}. This is a low-level function! GnuCash code should use @code{xaccGUIDNew}. @end deftypefun diff --git a/src/engine/SchedXaction.c b/src/engine/SchedXaction.c index c794bac407..2f8a47f359 100644 --- a/src/engine/SchedXaction.c +++ b/src/engine/SchedXaction.c @@ -380,6 +380,7 @@ xaccSchedXactionInit(SchedXaction *sx, QofBook *book) { Account *ra; const GncGUID *guid; + gchar guidstr[GUID_ENCODING_LENGTH+1]; qof_instance_init_data (&sx->inst, GNC_ID_SCHEDXACTION, book); @@ -387,7 +388,8 @@ xaccSchedXactionInit(SchedXaction *sx, QofBook *book) sx->template_acct = xaccMallocAccount(book); guid = qof_instance_get_guid( sx ); xaccAccountBeginEdit( sx->template_acct ); - xaccAccountSetName( sx->template_acct, guid_to_string( guid )); + guid_to_string_buff( guid, guidstr ); + xaccAccountSetName( sx->template_acct, guidstr); xaccAccountSetCommodity (sx->template_acct, gnc_commodity_table_lookup( gnc_commodity_table_get_table(book), diff --git a/src/engine/Split.c b/src/engine/Split.c index 53fa590474..1d539e428f 100644 --- a/src/engine/Split.c +++ b/src/engine/Split.c @@ -1450,8 +1450,10 @@ xaccSplitConvertAmount (const Split *split, const Account * account) xaccAccountGetCommodity(xaccSplitGetAccount(osplit)); if (!gnc_commodity_equal(to_commodity, split_comm)) { + gchar guidstr[GUID_ENCODING_LENGTH+1]; + guid_to_string_buff(xaccSplitGetGUID(osplit),guidstr); PERR("The split's (%s) amount can't be converted from %s into %s.", - guid_to_string(xaccSplitGetGUID(osplit)), + guidstr, gnc_commodity_get_mnemonic(split_comm), gnc_commodity_get_mnemonic(to_commodity) ); diff --git a/src/engine/Transaction.c b/src/engine/Transaction.c index 5146826b01..5a0d634de4 100644 --- a/src/engine/Transaction.c +++ b/src/engine/Transaction.c @@ -971,8 +971,10 @@ xaccTransEqual(const Transaction *ta, const Transaction *tb, if (!node_b) { - PINFO ("first has split %s and second does not", - guid_to_string (xaccSplitGetGUID (split_a))); + gchar guidstr[GUID_ENCODING_LENGTH+1]; + guid_to_string_buff (xaccSplitGetGUID (split_a),guidstr); + + PINFO ("first has split %s and second does not",guidstr); return FALSE; } diff --git a/src/engine/gncBillTerm.c b/src/engine/gncBillTerm.c index 9f2c7b97dd..d65b1bd264 100644 --- a/src/engine/gncBillTerm.c +++ b/src/engine/gncBillTerm.c @@ -266,9 +266,10 @@ GncBillTerm * gncBillTermCreate (QofBook *book) void gncBillTermDestroy (GncBillTerm *term) { + gchar guidstr[GUID_ENCODING_LENGTH+1]; if (!term) return; - DEBUG("destroying bill term %s (%p)", - guid_to_string(qof_instance_get_guid(&term->inst)), term); + guid_to_string_buff(qof_instance_get_guid(&term->inst),guidstr); + DEBUG("destroying bill term %s (%p)", guidstr, term); qof_instance_set_destroying(term, TRUE); qof_instance_set_dirty (&term->inst); gncBillTermCommitEdit (term); diff --git a/src/engine/test-core/test-engine-stuff.c b/src/engine/test-core/test-engine-stuff.c index 77086f0f4d..7e5b57ea89 100644 --- a/src/engine/test-core/test-engine-stuff.c +++ b/src/engine/test-core/test-engine-stuff.c @@ -243,7 +243,7 @@ get_random_guid(void) GncGUID *ret; ret = g_new(GncGUID, 1); - guid_new(ret); + guid_replace(ret); return ret; } diff --git a/src/engine/test/test-customer.c b/src/engine/test/test-customer.c index fe8fb2f6b7..fd84729188 100644 --- a/src/engine/test/test-customer.c +++ b/src/engine/test/test-customer.c @@ -90,7 +90,7 @@ test_customer (void) do_test (gncCustomerGetAddr (customer) != NULL, "Addr"); do_test (gncCustomerGetShipAddr (customer) != NULL, "ShipAddr"); - guid_new (&guid); + guid_replace (&guid); customer = gncCustomerCreate (book); count++; gncCustomerSetGUID (customer, &guid); diff --git a/src/engine/test/test-employee.c b/src/engine/test/test-employee.c index 1835bbf21c..3f3fdb3a7a 100644 --- a/src/engine/test/test-employee.c +++ b/src/engine/test/test-employee.c @@ -96,7 +96,7 @@ test_employee (void) do_test (gncEmployeeGetAddr (employee) != NULL, "Addr"); - guid_new (&guid); + guid_replace (&guid); employee = gncEmployeeCreate (book); count++; gncEmployeeSetGUID (employee, &guid); diff --git a/src/engine/test/test-guid.c b/src/engine/test/test-guid.c index 20c234a13d..fdb2408eb3 100644 --- a/src/engine/test/test-guid.c +++ b/src/engine/test/test-guid.c @@ -42,11 +42,12 @@ static void test_null_guid(void) GncGUID *gp; g = guid_new_return(); - gp = guid_malloc(); - guid_new(gp); + gp = guid_new(); do_test(guid_equal(guid_null(), guid_null()), "null guids equal"); do_test(!guid_equal(&g, gp), "two guids equal"); + + guid_free(gp); } static void @@ -70,7 +71,7 @@ run_test (void) for (i = 0; i < NENT; i++) { ent = g_object_new(QOF_TYPE_INSTANCE, NULL); - guid_new(&guid); + guid_replace(&guid); ent = g_object_new(QOF_TYPE_INSTANCE, "guid", &guid, NULL); do_test ((NULL == qof_collection_lookup_entity (col, &guid)), "duplicate guid"); diff --git a/src/engine/test/test-job.c b/src/engine/test/test-job.c index 243307fff0..2b5b4f8155 100644 --- a/src/engine/test/test-job.c +++ b/src/engine/test/test-job.c @@ -91,7 +91,7 @@ test_job (void) test_bool_fcn (book, "Active", gncJobSetActive, gncJobGetActive); - guid_new (&guid); + guid_replace (&guid); job = gncJobCreate (book); count++; gncJobSetGUID (job, &guid); diff --git a/src/engine/test/test-vendor.c b/src/engine/test/test-vendor.c index c36ff72b1f..3f030e5c8e 100644 --- a/src/engine/test/test-vendor.c +++ b/src/engine/test/test-vendor.c @@ -96,7 +96,7 @@ test_vendor (void) do_test (gncVendorGetAddr (vendor) != NULL, "Addr"); - guid_new (&guid); + guid_replace (&guid); vendor = gncVendorCreate (book); count++; gncVendorSetGUID (vendor, &guid); diff --git a/src/engine/test/utest-Split.cpp b/src/engine/test/utest-Split.cpp index e4165e578c..fa149b95e1 100644 --- a/src/engine/test/utest-Split.cpp +++ b/src/engine/test/utest-Split.cpp @@ -974,6 +974,7 @@ test_xaccSplitConvertAmount (void) "GNCXX", "", 1000); gnc_commodity *gnm = gnc_commodity_new (book, "Gnome, Inc.", "NYSE", "GNM", "", 1000); + gchar guidstr[GUID_ENCODING_LENGTH+1]; Account *acc = xaccMallocAccount (book); Account *o_acc = xaccMallocAccount (book); @@ -991,7 +992,8 @@ test_xaccSplitConvertAmount (void) TestErrorStruct check = { loglevel, logdomain, NULL, 0 }; GLogFunc oldlogger = g_log_set_default_handler ((GLogFunc)test_null_handler, &check); - check.msg = g_strdup_printf ("[xaccSplitConvertAmount()] The split's (%s) amount can't be converted from GNCXX into GNM.", guid_to_string(xaccSplitGetGUID(o_split))); + guid_to_string_buff(xaccSplitGetGUID(o_split), guidstr); + check.msg = g_strdup_printf ("[xaccSplitConvertAmount()] The split's (%s) amount can't be converted from GNCXX into GNM.", guidstr); xaccAccountSetCommodity (acc, gnaira); xaccAccountSetCommodity (o_acc, gnaira); xaccAccountSetCommodity (ya_acc, gnm); diff --git a/src/experimental/cgi-bin/gnc-server.c b/src/experimental/cgi-bin/gnc-server.c index 4e19a76172..719bb67196 100644 --- a/src/experimental/cgi-bin/gnc-server.c +++ b/src/experimental/cgi-bin/gnc-server.c @@ -105,7 +105,7 @@ GList * logged_in_users = NULL; */ static const char * -auth_user (const char * name, const char *passwd) +auth_user (const char * name, const char *passwd, char *buff) { GncGUID *guid; const char *session_auth_string; @@ -115,11 +115,11 @@ auth_user (const char * name, const char *passwd) */ if (!name || !passwd) return NULL; - guid = g_new (GncGUID, 1); - guid_new (guid); + guid = guid_new(); logged_in_users = g_list_prepend (logged_in_users, guid); - session_auth_string = guid_to_string (guid); /* THREAD UNSAFE */ - return session_auth_string; + + guid_to_string_buffer (guid, buff); + return buff; } /* @@ -244,6 +244,7 @@ main (int argc, char *argv[]) const char *user_agent; const char *auth_string; const char *content_length; + gchar guidstr[GUID_ENCODING_LENGTH+1]; int read_len = 0; int send_accts = 0; @@ -301,7 +302,7 @@ main (int argc, char *argv[]) char *name = NULL, *passwd = NULL; parse_for_login (request_bufp, &name, &passwd); - auth_string = auth_user (name, passwd); + auth_string = auth_user (name, passwd, guidstr); if (!auth_string) { reject_auth(); diff --git a/src/gnome/dialog-print-check.c b/src/gnome/dialog-print-check.c index 3ee4f0f2a8..b024b4bc4b 100644 --- a/src/gnome/dialog-print-check.c +++ b/src/gnome/dialog-print-check.c @@ -767,7 +767,7 @@ pcd_save_custom_data(PrintCheckDialog *pcd, const gchar *title) multip = pcd_get_custom_multip(pcd); key_file = g_key_file_new(); - guid_new(&guid); + guid_replace(&guid); guid_to_string_buff(&guid, buf); g_key_file_set_string(key_file, KF_GROUP_TOP, KF_KEY_GUID, buf); g_key_file_set_string(key_file, KF_GROUP_TOP, KF_KEY_TITLE, title); diff --git a/src/gnome/dialog-print-check2.c b/src/gnome/dialog-print-check2.c index b9a2cc4ffc..0f707fd2a0 100644 --- a/src/gnome/dialog-print-check2.c +++ b/src/gnome/dialog-print-check2.c @@ -767,7 +767,7 @@ pcd_save_custom_data(PrintCheckDialog *pcd, const gchar *title) multip = pcd_get_custom_multip(pcd); key_file = g_key_file_new(); - guid_new(&guid); + guid_replace(&guid); guid_to_string_buff(&guid, buf); g_key_file_set_string(key_file, KF_GROUP_TOP, KF_KEY_GUID, buf); g_key_file_set_string(key_file, KF_GROUP_TOP, KF_KEY_TITLE, title); diff --git a/src/gnome/dialog-sx-editor.c b/src/gnome/dialog-sx-editor.c index cdc3e87d7f..2013a5e055 100644 --- a/src/gnome/dialog-sx-editor.c +++ b/src/gnome/dialog-sx-editor.c @@ -1285,9 +1285,7 @@ schedXact_editor_create_ledger( GncSxEditorDialog *sxed ) GtkWidget *main_vbox; /* Create the ledger */ - /* THREAD-UNSAFE */ - sxed->sxGUIDstr = g_strdup( guid_to_string( - xaccSchedXactionGetGUID(sxed->sx) ) ); + sxed->sxGUIDstr = guid_to_string( xaccSchedXactionGetGUID(sxed->sx) ); sxed->ledger = gnc_ledger_display_template_gl( sxed->sxGUIDstr ); splitreg = gnc_ledger_display_get_split_register( sxed->ledger ); diff --git a/src/gnome/dialog-sx-editor2.c b/src/gnome/dialog-sx-editor2.c index a5c5d61a11..1344f4402a 100644 --- a/src/gnome/dialog-sx-editor2.c +++ b/src/gnome/dialog-sx-editor2.c @@ -1276,8 +1276,7 @@ schedXact_editor_create_ledger (GncSxEditorDialog2 *sxed) GtkWidget *label; /* Create the ledger */ - /* THREAD-UNSAFE */ - sxed->sxGUIDstr = g_strdup (guid_to_string (xaccSchedXactionGetGUID (sxed->sx))); + sxed->sxGUIDstr = guid_to_string (xaccSchedXactionGetGUID (sxed->sx)); sxed->ledger = gnc_ledger_display2_template_gl (sxed->sxGUIDstr); model = gnc_ledger_display2_get_split_model_register (sxed->ledger); diff --git a/src/gnome/gnc-budget-view.c b/src/gnome/gnc-budget-view.c index 268699babb..a497cced2a 100644 --- a/src/gnome/gnc-budget-view.c +++ b/src/gnome/gnc-budget-view.c @@ -289,6 +289,7 @@ gbv_create_widget(GncBudgetView *view) GtkTreeIter iter; GtkWidget* h_separator; gchar *state_section; + gchar guidstr[GUID_ENCODING_LENGTH+1]; priv = GNC_BUDGET_VIEW_GET_PRIVATE(view); vbox = GTK_VBOX(view); @@ -315,7 +316,8 @@ gbv_create_widget(GncBudgetView *view) tree_view = gnc_tree_view_account_new(FALSE); gtk_container_add(GTK_CONTAINER(inner_scrolled_window), GTK_WIDGET(tree_view)); - state_section = g_strjoin(" ", STATE_SECTION_PREFIX, guid_to_string(&priv->key), NULL); + guid_to_string_buff(&priv->key, guidstr); + state_section = g_strjoin(" ", STATE_SECTION_PREFIX, guidstr, NULL); g_object_set(G_OBJECT(tree_view), "state-section", state_section, NULL); g_free (state_section); @@ -487,13 +489,16 @@ void gnc_budget_view_delete_budget(GncBudgetView *view) { GncBudgetViewPrivate *priv; + gchar guidstr[GUID_ENCODING_LENGTH+1]; g_return_if_fail(view != NULL); ENTER("view %p", view); priv = GNC_BUDGET_VIEW_GET_PRIVATE (view); - gnc_state_drop_sections_for (guid_to_string (&priv->key)); + + guid_to_string_buff(&priv->key, guidstr); + gnc_state_drop_sections_for (guidstr); g_object_set (G_OBJECT (priv->tree_view), "state-section", NULL, NULL); LEAVE(" "); diff --git a/src/gnome/gnc-plugin-page-account-tree.c b/src/gnome/gnc-plugin-page-account-tree.c index d191044bcf..9c3df362e5 100644 --- a/src/gnome/gnc-plugin-page-account-tree.c +++ b/src/gnome/gnc-plugin-page-account-tree.c @@ -1397,7 +1397,7 @@ gnc_plugin_page_account_tree_cmd_delete_account (GtkAction *action, GncPluginPag { GList *acct_list, *ptr; const GncGUID *guid; - const gchar *guid_str; + gchar guidstr[GUID_ENCODING_LENGTH+1]; gnc_set_busy_cursor(NULL, TRUE); gnc_suspend_gui_refresh (); @@ -1435,16 +1435,16 @@ gnc_plugin_page_account_tree_cmd_delete_account (GtkAction *action, GncPluginPag for (ptr = acct_list; ptr; ptr = g_list_next(ptr)) { guid = xaccAccountGetGUID (ptr->data); - guid_str = guid_to_string (guid); - gnc_state_drop_sections_for (guid_str); + guid_to_string_buff (guid, guidstr); + gnc_state_drop_sections_for (guidstr); } g_list_free(acct_list); /* Drop all references from the state file for this account */ guid = xaccAccountGetGUID (account); - guid_str = guid_to_string (guid); - gnc_state_drop_sections_for (guid_str); + guid_to_string_buff (guid, guidstr); + gnc_state_drop_sections_for (guidstr); /* * Finally, delete the account, any subaccounts it may still diff --git a/src/gnome/gnc-split-reg.c b/src/gnome/gnc-split-reg.c index e5e56ac745..544360b2e3 100644 --- a/src/gnome/gnc-split-reg.c +++ b/src/gnome/gnc-split-reg.c @@ -385,16 +385,15 @@ static void gsr_create_table( GNCSplitReg *gsr ) { - GtkWidget *register_widget; - SplitRegister *sr; + GtkWidget *register_widget = NULL; + SplitRegister *sr = NULL; - gchar *state_section; - const GncGUID * guid; - Account * account; - - account = gnc_ledger_display_leader(gsr->ledger); - guid = xaccAccountGetGUID(account); - state_section = g_strconcat (STATE_SECTION_REG_PREFIX, " ", (gchar*)guid_to_string (guid), NULL); + Account * account = gnc_ledger_display_leader(gsr->ledger); + const GncGUID * guid = xaccAccountGetGUID(account); + gchar guidstr[GUID_ENCODING_LENGTH+1]; + gchar *state_section = NULL; + guid_to_string_buff(guid, guidstr); + state_section = g_strconcat (STATE_SECTION_REG_PREFIX, " ", guidstr, NULL); ENTER("gsr=%p", gsr); @@ -693,13 +692,14 @@ gnc_split_reg_ld_destroy( GNCLedgerDisplay *ledger ) { GNCSplitReg *gsr = gnc_ledger_display_get_user_data( ledger ); + Account * account = gnc_ledger_display_leader(ledger); + const GncGUID * guid = xaccAccountGetGUID(account); + gchar guidstr[GUID_ENCODING_LENGTH+1]; gchar *state_section; - const GncGUID * guid; - Account * account; - account = gnc_ledger_display_leader(ledger); - guid = xaccAccountGetGUID(account); - state_section = g_strconcat (STATE_SECTION_REG_PREFIX, " ",(gchar*)guid_to_string (guid), NULL); + guid_to_string_buff(guid, guidstr); + + state_section = g_strconcat (STATE_SECTION_REG_PREFIX, " ", guidstr, NULL); if (gsr) { diff --git a/src/gnome/gnc-split-reg2.c b/src/gnome/gnc-split-reg2.c index 429b983ec4..4dfa3533b2 100644 --- a/src/gnome/gnc-split-reg2.c +++ b/src/gnome/gnc-split-reg2.c @@ -262,9 +262,17 @@ gsr2_create_table (GNCSplitReg2 *gsr) if (ledger_type == LD2_GL && model->type == GENERAL_LEDGER2) state_section = g_strdup (STATE_SECTION_GEN_LEDGER); else if (ledger_type == LD2_SUBACCOUNT) - state_section = g_strconcat (STATE_SECTION_REG_PREFIX, " ", (gchar*)guid_to_string (guid), " w/subaccounts", NULL); + { + gchar guidstr[GUID_ENCODING_LENGTH+1]; + guid_to_string_buff (guid, guidstr); + state_section = g_strconcat (STATE_SECTION_REG_PREFIX, " ", guidstr, " w/subaccounts", NULL); + } else - state_section = g_strconcat (STATE_SECTION_REG_PREFIX, " ", (gchar*)guid_to_string (guid), NULL); + { + gchar guidstr[GUID_ENCODING_LENGTH+1]; + guid_to_string_buff (guid, guidstr); + state_section = g_strconcat (STATE_SECTION_REG_PREFIX, " ", guidstr, NULL); + } g_object_set (G_OBJECT (view), "state-section", state_section, "show-column-menu", FALSE, NULL); @@ -680,31 +688,6 @@ gsr2_redraw_all_cb (GncTreeViewSplitReg *view, gpointer user_data) static void gnc_split_reg2_ld_destroy (GNCLedgerDisplay2 *ledger) { - GNCSplitReg2 *gsr = gnc_ledger_display2_get_user_data (ledger); - - gchar *state_key; - const GncGUID * guid; - Account * account; - - account = gnc_ledger_display2_leader (ledger); - guid = xaccAccountGetGUID (account); - state_key = (gchar*)guid_to_string (guid); - - if (gsr) - { - GncTreeModelSplitReg *model; - - model = gnc_ledger_display2_get_split_model_register (ledger); - -/*FIXME This may not be required - if (model && model->table) - gnc_table_save_state (model->table, state_key); -*/ - /* - * Don't destroy the window here any more. The register no longer - * owns it. - */ - } gnc_ledger_display2_set_user_data (ledger, NULL); } diff --git a/src/gnome/top-level.c b/src/gnome/top-level.c index f9043e4981..9a145d638d 100644 --- a/src/gnome/top-level.c +++ b/src/gnome/top-level.c @@ -309,7 +309,7 @@ static void gnc_save_all_state (gpointer session, gpointer unused) { QofBook *book; - const gchar *guid_string; + gchar guid_string[GUID_ENCODING_LENGTH+1]; const GncGUID *guid; GError *error = NULL; GKeyFile *keyfile = NULL; @@ -338,7 +338,7 @@ gnc_save_all_state (gpointer session, gpointer unused) /* Store the book's GncGUID in the top level group */ book = qof_session_get_book(session); guid = qof_entity_get_guid(QOF_INSTANCE(book)); - guid_string = guid_to_string(guid); + guid_to_string_buff(guid, guid_string); g_key_file_set_string(keyfile, STATE_FILE_TOP, STATE_FILE_BOOK_GUID, guid_string); diff --git a/src/import-export/log-replay/gnc-log-replay.c b/src/import-export/log-replay/gnc-log-replay.c index bbd26d73e0..198964ba4f 100644 --- a/src/import-export/log-replay/gnc-log-replay.c +++ b/src/import-export/log-replay/gnc-log-replay.c @@ -284,11 +284,13 @@ static void dump_split_record(split_record record) } if (record.trans_guid_present) { - DEBUG("Transaction GncGUID: %s", guid_to_string (&(record.trans_guid))); + guid_to_string_buff(&record.trans_guid, string_buf); + DEBUG("Transaction GncGUID: %s", string_buf); } if (record.split_guid_present) { - DEBUG("Split GncGUID: %s", guid_to_string (&(record.split_guid))); + guid_to_string_buff(&record.split_guid, string_buf); + DEBUG("Split GncGUID: %s", string_buf); } if (record.log_date_present) { @@ -307,7 +309,8 @@ static void dump_split_record(split_record record) } if (record.acc_guid_present) { - DEBUG("Account GncGUID: %s", guid_to_string (&(record.acc_guid))); + guid_to_string_buff(&record.trans_guid, string_buf); + DEBUG("Account GncGUID: %s", string_buf); } if (record.acc_name_present) { diff --git a/src/libqof/qof/Makefile.am b/src/libqof/qof/Makefile.am index 8bc270d08d..a1e3552090 100644 --- a/src/libqof/qof/Makefile.am +++ b/src/libqof/qof/Makefile.am @@ -75,7 +75,6 @@ qofinclude_HEADERS = \ qof-gobject.h noinst_HEADERS = \ - md5.h \ qofbook-p.h \ qofclass-p.h \ qofevent-p.h \ @@ -84,14 +83,6 @@ noinst_HEADERS = \ qofquery-p.h \ qofquerycore-p.h \ qofsession-p.h - -# Must compile md5.c without strict aliasing, otherwise function md5_finish_ctx -# gets "dereferencing type-punned pointer will break strict-aliasing rules" -noinst_LTLIBRARIES = libmd5.la -libmd5_la_SOURCES = md5.c -libmd5_la_CFLAGS = ${AM_CFLAGS} -fno-strict-aliasing - -libgnc_qof_la_LIBADD += libmd5.la EXTRA_DIST += \ qofmath128.cpp diff --git a/src/libqof/qof/guid.cpp b/src/libqof/qof/guid.cpp index 7f09eca911..73b913a2c1 100644 --- a/src/libqof/qof/guid.cpp +++ b/src/libqof/qof/guid.cpp @@ -1,6 +1,7 @@ /********************************************************************\ * guid.c -- globally unique ID implementation * * Copyright (C) 2000 Dave Peticolas * + * Copyright (C) 2014 Aaron Laws * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * @@ -21,10 +22,8 @@ * * \********************************************************************/ -#ifdef __cplusplus extern "C" { -#endif #ifdef HAVE_CONFIG_H # include @@ -51,32 +50,17 @@ extern "C" # include #endif #include "qof.h" -#include "md5.h" -#ifdef __cplusplus } -#endif +#include +#include +#include +#include +#include -# ifndef P_tmpdir -# define P_tmpdir "/tmp" -# endif +using namespace std; -/* Constants *******************************************************/ -#define DEBUG_GUID 0 -#define BLOCKSIZE 4096 -#ifdef G_PLATFORM_WIN32 -/* Win32 has a smaller pool of random bits, but the displayed warning confuses - * really a lot of people. Hence, I think we'd better switch off this warning - * for this particular known case. */ -# define THRESHOLD 1500 -#else -# define THRESHOLD (2 * BLOCKSIZE) -#endif - - -/* Static global variables *****************************************/ -static gboolean guid_initialized = FALSE; -static struct md5_ctx guid_context; +typedef boost::uuids::uuid gg; /* This static indicates the debugging module that this .o belongs to. */ static QofLogModule log_module = QOF_MOD_ENGINE; @@ -101,12 +85,22 @@ gnc_value_get_guid (const GValue *value) return val; } +static GncGUID * nullguid {reinterpret_cast (new boost::uuids::uuid{0})}; + +/*It looks like we are expected to provide the same pointer every time from this function*/ +const GncGUID * +guid_null (void) +{ + return nullguid; +} /* Memory management routines ***************************************/ + GncGUID * guid_malloc (void) { - return g_slice_new(GncGUID); + /*Note, the Boost uuid is a POD, so its constructor is trivial*/ + return reinterpret_cast (new boost::uuids::uuid); } void @@ -114,634 +108,128 @@ guid_free (GncGUID *guid) { if (!guid) return; - - g_slice_free(GncGUID, guid); + if (guid == nullguid) + /*!!Don't delete that!!*/ + return; + delete reinterpret_cast (guid); + guid = nullptr; } GncGUID * guid_copy (const GncGUID *guid) { - GncGUID *copy; - - g_return_val_if_fail(guid, NULL); - copy = guid_malloc(); - *copy = *guid; - return copy; -} - -const GncGUID * -guid_null(void) -{ - static int null_inited = 0; - static GncGUID null_guid; - - if (!null_inited) - { - int i; - - for (i = 0; i < GUID_DATA_SIZE; i++) - null_guid.data[i] = '\0'; - - null_inited = 1; - } - - return &null_guid; -} - -/* Function implementations ****************************************/ - -/* This code is based on code in md5.c in GNU textutils. */ -static size_t -init_from_stream(FILE *stream, size_t max_size) -{ - char buffer[BLOCKSIZE + 72]; - size_t sum, block_size, total; - - ENTER(""); - - if (max_size <= 0) - { - LEAVE("max_size is 0 or less, skipping stream"); - return 0; - } - - total = 0; - - /* Iterate over file contents. */ - while (1) - { - /* We read the file in blocks of BLOCKSIZE bytes. One call of the - * computation function processes the whole buffer so that with the - * next round of the loop another block can be read. */ - size_t n; - sum = 0; - - if (max_size < BLOCKSIZE) - block_size = max_size; - else - block_size = BLOCKSIZE; - - /* Read block. Take care for partial reads. */ - do - { - n = fread (buffer + sum, 1, block_size - sum, stream); - - sum += n; - } - while (sum < block_size && n != 0); - - max_size -= sum; - - if (n == 0 && ferror (stream)) - { - LEAVE("error while reading stream"); - return total; - } - - /* If end of file or max_size is reached, end the loop. */ - if ((n == 0) || (max_size == 0)) - break; - - /* Process buffer with BLOCKSIZE bytes. Note that - * BLOCKSIZE % 64 == 0 */ - md5_process_block (buffer, BLOCKSIZE, &guid_context); - - total += sum; - } - - /* Add the last bytes if necessary. */ - if (sum > 0) - { - md5_process_bytes (buffer, sum, &guid_context); - total += sum; - } - - LEAVE(""); - return total; -} - -static size_t -init_from_file(const char *filename, size_t max_size) -{ - struct stat stats; - size_t total = 0; - size_t file_bytes; - FILE *fp; - - ENTER("filename: %s", filename); - - memset(&stats, 0, sizeof(stats)); - if (g_stat(filename, &stats) != 0) - { - LEAVE("unable to read file stats on %s", filename); - return 0; - } - - md5_process_bytes(&stats, sizeof(stats), &guid_context); - total += sizeof(stats); - - if (max_size <= 0) - { - LEAVE("no bytes in file %s", filename); - return total; - } - - fp = g_fopen (filename, "r"); - if (fp == NULL) - { - LEAVE("unable to open file %s", filename); - return total; - } - - file_bytes = init_from_stream(fp, max_size); - -#ifdef HAVE_SCANF_LLD - PINFO ("guid_init got %" G_GUINT64_FORMAT " bytes from %s", - (guint64) file_bytes, - filename); -#else - PINFO ("guid_init got %lu bytes from %s", (unsigned long int) file_bytes, - filename); -#endif - - total += file_bytes; - - fclose(fp); - - LEAVE("file %s processed successfully", filename); - return total; -} - -static size_t -init_from_dir(const char *dirname, unsigned int max_files) -{ - char filename[1024]; - const gchar *de; - struct stat stats; - size_t total; - int result; - GDir *dir; - - ENTER("dirname: %s", dirname); - if (max_files <= 0) - { - LEAVE("max_files is 0 or less, skipping directory %s", dirname); - return 0; - } - - dir = g_dir_open(dirname, 0, NULL); - if (dir == NULL) - { - LEAVE("unable to open directory %s", dirname); - return 0; - } - - total = 0; - - do - { - de = g_dir_read_name(dir); - if (de == NULL) - break; - - md5_process_bytes(de, strlen(de), &guid_context); - total += strlen(de); - - result = g_snprintf(filename, sizeof(filename), - "%s/%s", dirname, de); - if ((result < 0) || (result >= (int)sizeof(filename))) - continue; - - memset(&stats, 0, sizeof(stats)); - if (g_stat(filename, &stats) != 0) - continue; - md5_process_bytes(&stats, sizeof(stats), &guid_context); - total += sizeof(stats); - - max_files--; - } - while (max_files > 0); - - g_dir_close(dir); - - LEAVE(""); - return total; -} - -static size_t -init_from_time(void) -{ - size_t total; - time64 time; -#ifdef HAVE_SYS_TIMES_H - clock_t clocks; - struct tms tms_buf; -#endif - - ENTER(""); - - total = 0; - - time = gnc_time (NULL); - md5_process_bytes(&time, sizeof(time), &guid_context); - total += sizeof(time); - -#ifdef HAVE_SYS_TIMES_H - clocks = times(&tms_buf); - md5_process_bytes(&clocks, sizeof(clocks), &guid_context); - md5_process_bytes(&tms_buf, sizeof(tms_buf), &guid_context); - total += sizeof(clocks) + sizeof(tms_buf); -#endif - - LEAVE(""); - return total; -} - -static size_t -init_from_int(int val) -{ - ENTER(""); - md5_process_bytes(&val, sizeof(val), &guid_context); - LEAVE(""); - return sizeof(int); -} - -static size_t -init_from_buff(unsigned char * buf, size_t buflen) -{ - ENTER(""); - md5_process_bytes(buf, buflen, &guid_context); - LEAVE(""); - return buflen; + const boost::uuids::uuid * old {reinterpret_cast (guid)}; + boost::uuids::uuid * ret {new boost::uuids::uuid (*old)}; + return reinterpret_cast (ret); } +/*Takes an allocated guid pointer and constructs it in place*/ void -guid_init(void) +guid_replace (GncGUID *guid) { - size_t bytes = 0; - - ENTER(""); - - /* Not needed; taken care of on first malloc. - * guid_memchunk_init(); */ - - md5_init_ctx(&guid_context); - - /* entropy pool - * FIXME /dev/urandom doesn't exist on Windows. We should - * use the Windows native CryptGenRandom or RtlGenRandom - * functions. See - * http://en.wikipedia.org/wiki/CryptGenRandom */ - bytes += init_from_file ("/dev/urandom", 512); - - /* files - * FIXME none of these directories make sense on - * Windows. We should figure out some proper - * alternatives there. */ - { - const char * files[] = - { - "/etc/passwd", - "/proc/loadavg", - "/proc/meminfo", - "/proc/net/dev", - "/proc/rtc", - "/proc/self/environ", - "/proc/self/stat", - "/proc/stat", - "/proc/uptime", - NULL - }; - int i; - - for (i = 0; files[i] != NULL; i++) - bytes += init_from_file(files[i], BLOCKSIZE); - } - - /* directories - * Note: P_tmpdir is set to "\" by mingw (Windows) This seems to - * trigger unwanted network access attempts (see bug #521817). - * So on Windows we explicitly set the temporary directory. - * FIXME other than "c:/temp" none of these directories make sense on - * Windows. We should figure out some proper - * alternatives there. */ - { - const char * dirname; - const char * dirs[] = - { - "/proc", -#ifndef G_OS_WIN32 - P_tmpdir, -#else - "c:/temp", -#endif - "/var/lock", - "/var/log", - "/var/mail", - "/var/spool/mail", - "/var/run", - NULL - }; - int i; - - for (i = 0; dirs[i] != NULL; i++) - bytes += init_from_dir(dirs[i], 32); - - dirname = g_get_home_dir(); - if (dirname != NULL) - bytes += init_from_dir(dirname, 32); - } - - /* process and parent ids */ - { -#ifdef HAVE_UNISTD_H - pid_t pid; - - pid = getpid(); - md5_process_bytes(&pid, sizeof(pid), &guid_context); - bytes += sizeof(pid); - -#ifdef HAVE_GETPPID - pid = getppid(); - md5_process_bytes(&pid, sizeof(pid), &guid_context); - bytes += sizeof(pid); -#endif -#endif - } - - /* user info */ - { -#ifdef HAVE_GETUID - uid_t uid; - gid_t gid; - char *s; - - s = getlogin(); - if (s != NULL) - { - md5_process_bytes(s, strlen(s), &guid_context); - bytes += strlen(s); - } - - uid = getuid(); - md5_process_bytes(&uid, sizeof(uid), &guid_context); - bytes += sizeof(uid); - - gid = getgid(); - md5_process_bytes(&gid, sizeof(gid), &guid_context); - bytes += sizeof(gid); -#endif - } - - /* host info */ - { -#ifdef HAVE_GETHOSTNAME - char string[1024]; - - memset(string, 0, sizeof(string)); - gethostname(string, sizeof(string)); - md5_process_bytes(string, sizeof(string), &guid_context); - bytes += sizeof(string); -#endif - } - - /* plain old random */ - { - int n, i; - - srand((unsigned int) gnc_time (NULL)); - - for (i = 0; i < 32; i++) - { - n = rand(); - - md5_process_bytes(&n, sizeof(n), &guid_context); - bytes += sizeof(n); - } - } - - /* time in secs and clock ticks */ - bytes += init_from_time(); - - PINFO ("got %" G_GUINT64_FORMAT " bytes", (guint64) bytes); - - if (bytes < THRESHOLD) - PWARN("only got %" G_GUINT64_FORMAT " bytes.\n" - "The identifiers might not be very random.\n", - (guint64)bytes); - - guid_initialized = TRUE; - LEAVE(); + static boost::uuids::random_generator gen; + boost::uuids::uuid * val {reinterpret_cast (guid)}; + val->boost::uuids::uuid::~uuid (); + boost::uuids::uuid temp (gen ()); + val->swap (temp); } -void -guid_shutdown (void) +GncGUID * +guid_new (void) { -} - -#define GUID_PERIOD 5000 - -void -guid_new(GncGUID *guid) -{ - static int counter = 0; - struct md5_ctx ctx; - - if (guid == NULL) - return; - - if (!guid_initialized) - guid_init(); - - /* make the id */ - ctx = guid_context; - md5_finish_ctx(&ctx, guid->data); - - /* update the global context */ - init_from_time(); - - /* Make it a little extra salty. I think init_from_time was buggy, - * or something, since duplicate id's actually happened. Or something - * like that. I think this is because init_from_time kept returning - * the same values too many times in a row. So we'll do some 'block - * chaining', and feed in the old guid as new random data. - * - * Anyway, I think the whole fact that I saw a bunch of duplicate - * id's at one point, but can't reproduce the bug is rather alarming. - * Something must be broken somewhere, and merely adding more salt - * is just hiding the problem, not fixing it. - */ - init_from_int (433781 * counter); - init_from_buff (guid->data, GUID_DATA_SIZE); - - if (counter == 0) - { - FILE *fp; - - fp = g_fopen ("/dev/urandom", "r"); - if (fp == NULL) - return; - - init_from_stream(fp, 32); - - fclose(fp); - - counter = GUID_PERIOD; - } - - counter--; + GncGUID * ret {guid_malloc ()}; + guid_replace (ret); + return ret; } GncGUID -guid_new_return(void) +guid_new_return (void) { - GncGUID guid; - - guid_new (&guid); - - return guid; + /*we need to construct our value as a boost guid so that + it can be deconstructed (in place) in guid_replace*/ + boost::uuids::uuid guid; + GncGUID * ret {reinterpret_cast (&guid)}; + guid_replace (ret); + /*return a copy*/ + return *ret; } -/* needs 32 bytes exactly, doesn't print a null char */ -static void -encode_md5_data(const unsigned char *data, char *buffer) +gchar * +guid_to_string (const GncGUID * guid) { - size_t count; - - for (count = 0; count < GUID_DATA_SIZE; count++, buffer += 2) - sprintf(buffer, "%02x", data[count]); + /* We need to malloc here, not 'new' because it will be freed + by the caller which will use free (not delete).*/ + gchar * ret {reinterpret_cast (g_malloc (sizeof (gchar)*GUID_ENCODING_LENGTH+1))}; + gchar * temp {guid_to_string_buff (guid, ret)}; + if (!temp){ + g_free (ret); + return nullptr; + } + return ret; } -/* returns true if the first 32 bytes of buffer encode - * a hex number. returns false otherwise. Decoded number - * is packed into data in little endian order. */ -static gboolean -decode_md5_string(const gchar *string, unsigned char *data) +gchar * +guid_to_string_buff (const GncGUID * guid, gchar *str) { - unsigned char n1, n2; - size_t count = -1; - unsigned char c1, c2; + if (!str || !guid) return NULL; - if (NULL == data) return FALSE; - if (NULL == string) goto badstring; + boost::uuids::uuid const & tempg = *reinterpret_cast (guid); + unsigned destspot {0}; + string const & val {to_string (tempg)}; + for (auto val_char : val) + if (val_char != '-') + str [destspot++] = val_char; - for (count = 0; count < GUID_DATA_SIZE; count++) - { - /* check for a short string e.g. null string ... */ - if ((0 == string[2*count]) || (0 == string[2*count+1])) goto badstring; - - c1 = tolower(string[2 * count]); - if (!isxdigit(c1)) goto badstring; - - c2 = tolower(string[2 * count + 1]); - if (!isxdigit(c2)) goto badstring; - - if (isdigit(c1)) - n1 = c1 - '0'; - else - n1 = c1 - 'a' + 10; - - if (isdigit(c2)) - n2 = c2 - '0'; - else - n2 = c2 - 'a' + 10; - - data[count] = (n1 << 4) | n2; - } - return TRUE; - -badstring: - for (count = 0; count < GUID_DATA_SIZE; count++) - { - data[count] = 0; - } - return FALSE; -} - -/* Allocate the key */ - -const char * -guid_to_string(const GncGUID * guid) -{ -#ifdef G_THREADS_ENABLED -#ifndef HAVE_GLIB_2_32 - static GStaticPrivate guid_buffer_key = G_STATIC_PRIVATE_INIT; - gchar *string; - - string = static_cast(g_static_private_get (&guid_buffer_key)); - if (string == NULL) - { - string = static_cast(malloc(GUID_ENCODING_LENGTH + 1)); - g_static_private_set (&guid_buffer_key, string, g_free); - } -#else - static GPrivate guid_buffer_key = G_PRIVATE_INIT(g_free); - gchar *string; - - string = static_cast(g_private_get (&guid_buffer_key)); - if (string == NULL) - { - string = static_cast(malloc(GUID_ENCODING_LENGTH + 1)); - g_private_set (&guid_buffer_key, string); - } -#endif -#else - static char string[64]; -#endif - - encode_md5_data(guid->data, string); - string[GUID_ENCODING_LENGTH] = '\0'; - - return string; -} - -char * -guid_to_string_buff(const GncGUID * guid, char *string) -{ - if (!string || !guid) return NULL; - - encode_md5_data(guid->data, string); - - string[GUID_ENCODING_LENGTH] = '\0'; - return &string[GUID_ENCODING_LENGTH]; + str[GUID_ENCODING_LENGTH] = '\0'; + return &str[GUID_ENCODING_LENGTH]; } gboolean -string_to_guid(const char * string, GncGUID * guid) +string_to_guid (const char * str, GncGUID * guid) { - return decode_md5_string(string, (guid != NULL) ? guid->data : NULL); + if (!guid || !str) + return false; + + try + { + static boost::uuids::string_generator strgen; + boost::uuids::uuid * converted {reinterpret_cast (guid)}; + new (converted) boost::uuids::uuid (strgen (str)); + } + catch (...) + { + return false; + } + return true; } gboolean -guid_equal(const GncGUID *guid_1, const GncGUID *guid_2) +guid_equal (const GncGUID *guid_1, const GncGUID *guid_2) { - if (guid_1 && guid_2) - return (memcmp(guid_1, guid_2, GUID_DATA_SIZE) == 0); - else - return FALSE; + if (!guid_1 || !guid_2) + return false; + boost::uuids::uuid const * g1 {reinterpret_cast (guid_1)}; + boost::uuids::uuid const * g2 {reinterpret_cast (guid_2)}; + return *g1 == *g2; } gint -guid_compare(const GncGUID *guid_1, const GncGUID *guid_2) +guid_compare (const GncGUID *guid_1, const GncGUID *guid_2) { - if (guid_1 == guid_2) - return 0; - - /* nothing is always less than something */ - if (!guid_1 && guid_2) + boost::uuids::uuid const * g1 {reinterpret_cast (guid_1)}; + boost::uuids::uuid const * g2 {reinterpret_cast (guid_2)}; + if (*g1 < *g2) return -1; - - if (guid_1 && !guid_2) - return 1; - - return memcmp (guid_1, guid_2, GUID_DATA_SIZE); + if (*g1 == *g2) + return 0; + return 1; } guint guid_hash_to_guint (gconstpointer ptr) { - const GncGUID *guid = static_cast(ptr); + const boost::uuids::uuid * guid = reinterpret_cast (ptr); if (!guid) { @@ -749,33 +237,21 @@ guid_hash_to_guint (gconstpointer ptr) return 0; } - if (sizeof(guint) <= sizeof(guid->data)) + guint hash {0}; + unsigned retspot {0}; + for (auto guidspot : *guid) { - const guint* ptr_data = (const guint *) guid->data; - return (*ptr_data); - } - else - { - guint hash = 0; - unsigned int i, j; - - for (i = 0, j = 0; i < sizeof(guint); i++, j++) - { - if (j == GUID_DATA_SIZE) j = 0; - - hash <<= 4; - hash |= guid->data[j]; - } - - return hash; + hash <<= 4; + hash |= guidspot; } + return hash; } gint guid_g_hash_table_equal (gconstpointer guid_a, gconstpointer guid_b) { - return guid_equal (static_cast(guid_a), - static_cast(guid_b)); + return guid_equal (reinterpret_cast (guid_a), + reinterpret_cast (guid_b)); } GHashTable * @@ -798,7 +274,7 @@ gnc_string_to_guid (const GValue *src, GValue *dest) as_string = g_value_get_string (src); guid = g_new0 (GncGUID, 1); - string_to_guid(as_string, guid); + string_to_guid (as_string, guid); g_value_take_boxed (dest, guid); } diff --git a/src/libqof/qof/guid.h b/src/libqof/qof/guid.h index 0dabd4221b..7015e23503 100644 --- a/src/libqof/qof/guid.h +++ b/src/libqof/qof/guid.h @@ -1,6 +1,7 @@ /********************************************************************\ * guid.h -- globally unique ID User API * * Copyright (C) 2000 Dave Peticolas * + * 2014 Aaron Laws * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * @@ -35,114 +36,96 @@ extern "C" /** @addtogroup Entity @{ */ /** @addtogroup GncGUID - Globally Unique ID's provide a way to uniquely identify - some thing. A GncGUID is a unique, cryptographically + Globally Unique IDs provide a way to uniquely identify + something. A GncGUID is a unique, cryptographically random 128-bit value. The identifier is so random that it is safe to assume that there is no other such item on the planet Earth, and indeed, not even in the Galaxy or beyond. - QOF GncGUID's can be used independently of any other subsystem + QOF GncGUIDs can be used independently of any other subsystem in QOF. In particular, they do not require the use of - other parts of the object subsystem. New GncGUID's are usually - created by initialising a new entity using qof_instance_init, + other parts of the object subsystem. New GncGUIDs are usually + created by initializing a new entity using qof_instance_init, rather than calling GncGUID functions directly. @{ */ /** @file guid.h @brief globally unique ID User API @author Copyright (C) 2000 Dave Peticolas + Copyright 2014 Aaron Laws */ -/** The type used to store guids */ #define GUID_DATA_SIZE 16 -typedef union GNC_INTERNAL_GUID -{ - guchar data[GUID_DATA_SIZE]; - - gint __align_me; /* this just ensures that GUIDs are 32-bit - * aligned on systems that need them to be. */ -} GncGUID; - #define GNC_TYPE_GUID (gnc_guid_get_type()) #define GNC_VALUE_HOLDS_GUID(value) G_VALUE_HOLDS(value, GNC_TYPE_GUID) +/** The type used to store guids */ +typedef struct _gncGuid { + unsigned char reserved[GUID_DATA_SIZE]; +} GncGUID; + GType gnc_guid_get_type (void); const GncGUID* gnc_value_get_guid (const GValue *value); -/** number of characters needed to encode a guid as a string +/** Number of characters needed to encode a guid as a string * not including the null terminator. */ #define GUID_ENCODING_LENGTH 32 - -/** Initialize the id generator with a variety of random - * sources. +/** Generate a new guid. * - * @note Only one of guid_init(), guid_init_with_salt() and - * guid_init_only_salt() should be called. Calling any - * initialization function a second time will reset the generator and - * erase the effect of the first call. - */ -void guid_init(void); - -/** Release the memory chunk associated with gui storage. Use this - * only when shutting down the program, as it invalidates *all* - * GUIDs at once. */ -void guid_shutdown (void); - -/** Generate a new id. If no initialization function has been called, - * guid_init() will be called before the id is created. - * - * @param guid A pointer to an existing guid data structure. The + * @param guid A pointer to an allocated guid data structure. The * existing value will be replaced with a new value. - * - * This routine uses the md5 algorithm to build strong random guids. - * Note that while guid's are generated randomly, the odds of this - * routine returning a non-unique id are astronomically small. - * (Literally astronomically: If you had Cray's on every solar - * system in the universe running for the entire age of the universe, - * you'd still have less than a one-in-a-million chance of coming up - * with a duplicate id. 2^128 == 10^38 is a really really big number.) */ -void guid_new(GncGUID *guid); +void guid_replace (GncGUID *guid); -/** Generate a new id. If no initialization function has been called, - * guid_init() will be called before the id is created. +/** Generate a new id. * - * @return guid A data structure containing a newly allocated GncGUID. - * Caller is responsible for calling guid_free(). + * @return guid A data structure containing a copy of a newly constructed GncGUID. */ -GncGUID guid_new_return(void); +GncGUID guid_new_return (void); -/** Returns a GncGUID which is guaranteed -to never reference any entity. */ +/** Returns a GncGUID which is guaranteed to never reference any entity. + * + * Do not free this value! The same pointer is returned on each call.*/ const GncGUID * guid_null (void); -/** Efficiently allocate & free memory for GUIDs */ +/** + * Allocate memory for a GUID. This does not construct a GUID. In other words, + * the returned pointer has not necessarily been initialized. The returned + * pointer must be freed with * guid_free. + */ GncGUID * guid_malloc (void); -/* Return a guid set to all zero's */ +/** + * Allocate and construct a new GUID. The returned pointer must be + * released with guid_free. + */ +GncGUID * guid_new (void); + +/*Free the guid pointed to. Do not use this guid any more.*/ void guid_free (GncGUID *guid); +/** + * Returns a newly allocated GncGUID that matches the passed-in GUID. + * The returned pointer must be freed using guid_free. + */ GncGUID *guid_copy (const GncGUID *guid); /** The guid_to_string() routine returns a null-terminated string * encoding of the id. String encodings of identifiers are hex * numbers printed only with the characters '0' through '9' and * 'a' through 'f'. The encoding will always be GUID_ENCODING_LENGTH - * characters long. - * - * XXX This routine is not thread safe and is deprecated. Please - * use the routine guid_to_string_buff() instead. + * characters long (not including the null terminator). * * @param guid The guid to print. * * @return A pointer to the starting character of the string. The - * returned memory is owned by this routine and may not be freed by - * the caller. + * returned memory is owned by the calling routine and must be freed + * using g_free. */ -const gchar * guid_to_string (const GncGUID * guid); +gchar * guid_to_string (const GncGUID * guid); /** The guid_to_string_buff() routine puts a null-terminated string * encoding of the id into the memory pointed at by buff. The @@ -155,16 +138,21 @@ const gchar * guid_to_string (const GncGUID * guid); * * @param buff The buffer to print it into. * - * @return A pointer to the terminating null character of the string. + * @return A pointer to the terminating null character of the string, + * or, if no copy took place, NULL. */ gchar * guid_to_string_buff (const GncGUID * guid, /*@ out @*/ gchar *buff); -/** Given a string, decode the id into the guid if guid is non-NULL. - * The function returns TRUE if the string was a valid 32 character - * hexadecimal number. This function accepts both upper and lower case - * hex digits. If the return value is FALSE, the effect on guid is - * undefined. */ +/** Given a string, replace the given guid with the parsed one unless + * the given value is null. + * If null is passed as guid or string, false is returned and nothing + * is done, otherwise, the function returns true. + * This function accepts both uppor and lower case hex digits. If + * letters outside the range of [a-fA-F] are passed, they are silently + * replaced. If non-alphanumeric digits are given, this function will + * either return false or replace those values with others. + */ gboolean string_to_guid(const gchar * string, /*@ out @*/ GncGUID * guid); diff --git a/src/libqof/qof/kvp_frame.cpp b/src/libqof/qof/kvp_frame.cpp index 299eee5bdb..8d2fd84a0d 100644 --- a/src/libqof/qof/kvp_frame.cpp +++ b/src/libqof/qof/kvp_frame.cpp @@ -1568,9 +1568,9 @@ kvp_value_to_string(const KvpValue *val) break; case KVP_TYPE_GUID: - /* THREAD-UNSAFE */ - ctmp = guid_to_string(kvp_value_get_guid(val)); - tmp2 = g_strdup_printf("KVP_VALUE_GUID(%s)", ctmp ? ctmp : ""); + gchar guidstr[GUID_ENCODING_LENGTH+1]; + guid_to_string_buff(kvp_value_get_guid(val),guidstr); + tmp2 = g_strdup_printf("KVP_VALUE_GUID(%s)", guidstr); return tmp2; break; diff --git a/src/libqof/qof/md5.c b/src/libqof/qof/md5.c deleted file mode 100644 index 8912106663..0000000000 --- a/src/libqof/qof/md5.c +++ /dev/null @@ -1,445 +0,0 @@ -/* md5.c - Functions to compute MD5 message digest of files or memory blocks - according to the definition of MD5 in RFC 1321 from April 1992. - Copyright (C) 1995, 1996 Free Software Foundation, Inc. - NOTE: The canonical source of this file is maintained with the GNU C - Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu. - - 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, 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, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Ulrich Drepper , 1995. */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include - -#if STDC_HEADERS || defined _LIBC -# include -# include -#else -# ifndef HAVE_MEMCPY -#include -/* # define memcpy(d, s, n) bcopy ((s), (d), (n)) */ -# endif -#endif - -#include "md5.h" - -#ifdef _LIBC -# include -# if __BYTE_ORDER == __BIG_ENDIAN -# define WORDS_BIGENDIAN 1 -# endif -#endif - -#ifdef WORDS_BIGENDIAN -# define SWAP(n) \ - (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24)) -#else -# define SWAP(n) (n) -#endif - - -/* This array contains the bytes used to pad the buffer to the next - 64-byte boundary. (RFC 1321, 3.1: Step 1) */ -static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ }; - - -/* Initialize structure containing state of computation. - (RFC 1321, 3.3: Step 3) */ -void -md5_init_ctx (ctx) -struct md5_ctx *ctx; -{ - ctx->A = 0x67452301; - ctx->B = 0xefcdab89; - ctx->C = 0x98badcfe; - ctx->D = 0x10325476; - - ctx->total[0] = ctx->total[1] = 0; - ctx->buflen = 0; -} - -/* Put result from CTX in first 16 bytes following RESBUF. The result - must be in little endian byte order. - - IMPORTANT: On some systems it is required that RESBUF is correctly - aligned for a 32 bits value. */ -void * -md5_read_ctx (ctx, resbuf) -const struct md5_ctx *ctx; -void *resbuf; -{ - ((md5_uint32 *) resbuf)[0] = SWAP (ctx->A); - ((md5_uint32 *) resbuf)[1] = SWAP (ctx->B); - ((md5_uint32 *) resbuf)[2] = SWAP (ctx->C); - ((md5_uint32 *) resbuf)[3] = SWAP (ctx->D); - - return resbuf; -} - -/* Process the remaining bytes in the internal buffer and the usual - prolog according to the standard and write the result to RESBUF. - - IMPORTANT: On some systems it is required that RESBUF is correctly - aligned for a 32 bits value. */ -void * -md5_finish_ctx (ctx, resbuf) -struct md5_ctx *ctx; -void *resbuf; -{ - /* Take yet unprocessed bytes into account. */ - md5_uint32 bytes = ctx->buflen; - size_t pad; - - /* Now count remaining bytes. */ - ctx->total[0] += bytes; - if (ctx->total[0] < bytes) - ++ctx->total[1]; - - pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes; - memcpy (&ctx->buffer[bytes], fillbuf, pad); - - /* Put the 64-bit file length in *bits* at the end of the buffer. */ - *(md5_uint32 *) &ctx->buffer[bytes + pad] = SWAP (ctx->total[0] << 3); - *(md5_uint32 *) &ctx->buffer[bytes + pad + 4] = SWAP ((ctx->total[1] << 3) | - (ctx->total[0] >> 29)); - - /* Process last bytes. */ - md5_process_block (ctx->buffer, bytes + pad + 8, ctx); - - return md5_read_ctx (ctx, resbuf); -} - -/* Compute MD5 message digest for bytes read from STREAM. The - resulting message digest number will be written into the 16 bytes - beginning at RESBLOCK. */ -int -md5_stream (stream, resblock) -FILE *stream; -void *resblock; -{ - /* Important: BLOCKSIZE must be a multiple of 64. */ -#define BLOCKSIZE 4096 - struct md5_ctx ctx; - char buffer[BLOCKSIZE + 72]; - size_t sum; - - /* Initialize the computation context. */ - md5_init_ctx (&ctx); - - /* Iterate over full file contents. */ - while (1) - { - /* We read the file in blocks of BLOCKSIZE bytes. One call of the - computation function processes the whole buffer so that with the - next round of the loop another block can be read. */ - size_t n; - sum = 0; - - /* Read block. Take care for partial reads. */ - do - { - n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream); - - sum += n; - } - while (sum < BLOCKSIZE && n != 0); - if (n == 0 && ferror (stream)) - return 1; - - /* If end of file is reached, end the loop. */ - if (n == 0) - break; - - /* Process buffer with BLOCKSIZE bytes. Note that - BLOCKSIZE % 64 == 0 - */ - md5_process_block (buffer, BLOCKSIZE, &ctx); - } - - /* Add the last bytes if necessary. */ - if (sum > 0) - md5_process_bytes (buffer, sum, &ctx); - - /* Construct result in desired memory. */ - md5_finish_ctx (&ctx, resblock); - return 0; -} - -/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The - result is always in little endian byte order, so that a byte-wise - output yields to the wanted ASCII representation of the message - digest. */ -void * -md5_buffer (buffer, len, resblock) -const char *buffer; -size_t len; -void *resblock; -{ - struct md5_ctx ctx; - - /* Initialize the computation context. */ - md5_init_ctx (&ctx); - - /* Process whole buffer but last len % 64 bytes. */ - md5_process_bytes (buffer, len, &ctx); - - /* Put result in desired memory area. */ - return md5_finish_ctx (&ctx, resblock); -} - - -void -md5_process_bytes (buffer, len, ctx) -const void *buffer; -size_t len; -struct md5_ctx *ctx; -{ -#define NUM_MD5_WORDS 1024 - size_t add = 0; - - /* When we already have some bits in our internal buffer concatenate - both inputs first. */ - if (ctx->buflen != 0) - { - size_t left_over = ctx->buflen; - - add = 128 - left_over > len ? len : 128 - left_over; - - memcpy (&ctx->buffer[left_over], buffer, add); - ctx->buflen += add; - - if (left_over + add > 64) - { - md5_process_block (ctx->buffer, (left_over + add) & ~63, ctx); - /* The regions in the following copy operation cannot overlap. */ - memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~63], - (left_over + add) & 63); - ctx->buflen = (left_over + add) & 63; - } - - buffer = (const char *) buffer + add; - len -= add; - } - - /* Process available complete blocks. */ - if (len > 64) - { - if ((add & 3) == 0) /* buffer is still 32-bit aligned */ - { - md5_process_block (buffer, len & ~63, ctx); - buffer = (const char *) buffer + (len & ~63); - } - else /* buffer is not 32-bit aligned */ - { - md5_uint32 md5_buffer[NUM_MD5_WORDS]; - size_t num_bytes; - size_t buf_bytes; - - num_bytes = len & ~63; - while (num_bytes > 0) - { - buf_bytes = (num_bytes < sizeof(md5_buffer)) ? - num_bytes : sizeof(md5_buffer); - memcpy (md5_buffer, buffer, buf_bytes); - md5_process_block (md5_buffer, buf_bytes, ctx); - num_bytes -= buf_bytes; - buffer = (const char *) buffer + buf_bytes; - } - } - - len &= 63; - } - - /* Move remaining bytes in internal buffer. */ - if (len > 0) - { - memcpy (ctx->buffer, buffer, len); - ctx->buflen = len; - } -} - - -/* These are the four functions used in the four steps of the MD5 algorithm - and defined in the RFC 1321. The first function is a little bit optimized - (as found in Colin Plumbs public domain implementation). */ -/* #define FF(b, c, d) ((b & c) | (~b & d)) */ -#define FF(b, c, d) (d ^ (b & (c ^ d))) -#define FG(b, c, d) FF (d, b, c) -#define FH(b, c, d) (b ^ c ^ d) -#define FI(b, c, d) (c ^ (b | ~d)) - -/* Process LEN bytes of BUFFER, accumulating context into CTX. - It is assumed that LEN % 64 == 0. */ - -void -md5_process_block (buffer, len, ctx) -const void *buffer; -size_t len; -struct md5_ctx *ctx; -{ - md5_uint32 correct_words[16]; - const md5_uint32 *words = buffer; - size_t nwords = len / sizeof (md5_uint32); - const md5_uint32 *endp = words + nwords; - md5_uint32 A = ctx->A; - md5_uint32 B = ctx->B; - md5_uint32 C = ctx->C; - md5_uint32 D = ctx->D; - - /* First increment the byte count. RFC 1321 specifies the possible - length of the file up to 2^64 bits. Here we only compute the - number of bytes. Do a double word increment. */ - ctx->total[0] += len; - if (ctx->total[0] < len) - ++ctx->total[1]; - - /* Process all bytes in the buffer with 64 bytes in each round of - the loop. */ - while (words < endp) - { - md5_uint32 *cwp = correct_words; - md5_uint32 A_save = A; - md5_uint32 B_save = B; - md5_uint32 C_save = C; - md5_uint32 D_save = D; - - /* First round: using the given function, the context and a constant - the next context is computed. Because the algorithms processing - unit is a 32-bit word and it is determined to work on words in - little endian byte order we perhaps have to change the byte order - before the computation. To reduce the work for the next steps - we store the swapped words in the array CORRECT_WORDS. */ - -#define OP(a, b, c, d, s, T) \ - do \ - { \ - a += FF (b, c, d) + (*cwp++ = SWAP (*words)) + T; \ - ++words; \ - CYCLIC (a, s); \ - a += b; \ - } \ - while (0) - - /* It is unfortunate that C does not provide an operator for - cyclic rotation. Hope the C compiler is smart enough. */ -#define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s))) - - /* Before we start, one word to the strange constants. - They are defined in RFC 1321 as - - T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64 - */ - - /* Round 1. */ - OP (A, B, C, D, 7, 0xd76aa478); - OP (D, A, B, C, 12, 0xe8c7b756); - OP (C, D, A, B, 17, 0x242070db); - OP (B, C, D, A, 22, 0xc1bdceee); - OP (A, B, C, D, 7, 0xf57c0faf); - OP (D, A, B, C, 12, 0x4787c62a); - OP (C, D, A, B, 17, 0xa8304613); - OP (B, C, D, A, 22, 0xfd469501); - OP (A, B, C, D, 7, 0x698098d8); - OP (D, A, B, C, 12, 0x8b44f7af); - OP (C, D, A, B, 17, 0xffff5bb1); - OP (B, C, D, A, 22, 0x895cd7be); - OP (A, B, C, D, 7, 0x6b901122); - OP (D, A, B, C, 12, 0xfd987193); - OP (C, D, A, B, 17, 0xa679438e); - OP (B, C, D, A, 22, 0x49b40821); - - /* For the second to fourth round we have the possibly swapped words - in CORRECT_WORDS. Redefine the macro to take an additional first - argument specifying the function to use. */ -#undef OP -#define OP(f, a, b, c, d, k, s, T) \ - do \ - { \ - a += f (b, c, d) + correct_words[k] + T; \ - CYCLIC (a, s); \ - a += b; \ - } \ - while (0) - - /* Round 2. */ - OP (FG, A, B, C, D, 1, 5, 0xf61e2562); - OP (FG, D, A, B, C, 6, 9, 0xc040b340); - OP (FG, C, D, A, B, 11, 14, 0x265e5a51); - OP (FG, B, C, D, A, 0, 20, 0xe9b6c7aa); - OP (FG, A, B, C, D, 5, 5, 0xd62f105d); - OP (FG, D, A, B, C, 10, 9, 0x02441453); - OP (FG, C, D, A, B, 15, 14, 0xd8a1e681); - OP (FG, B, C, D, A, 4, 20, 0xe7d3fbc8); - OP (FG, A, B, C, D, 9, 5, 0x21e1cde6); - OP (FG, D, A, B, C, 14, 9, 0xc33707d6); - OP (FG, C, D, A, B, 3, 14, 0xf4d50d87); - OP (FG, B, C, D, A, 8, 20, 0x455a14ed); - OP (FG, A, B, C, D, 13, 5, 0xa9e3e905); - OP (FG, D, A, B, C, 2, 9, 0xfcefa3f8); - OP (FG, C, D, A, B, 7, 14, 0x676f02d9); - OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a); - - /* Round 3. */ - OP (FH, A, B, C, D, 5, 4, 0xfffa3942); - OP (FH, D, A, B, C, 8, 11, 0x8771f681); - OP (FH, C, D, A, B, 11, 16, 0x6d9d6122); - OP (FH, B, C, D, A, 14, 23, 0xfde5380c); - OP (FH, A, B, C, D, 1, 4, 0xa4beea44); - OP (FH, D, A, B, C, 4, 11, 0x4bdecfa9); - OP (FH, C, D, A, B, 7, 16, 0xf6bb4b60); - OP (FH, B, C, D, A, 10, 23, 0xbebfbc70); - OP (FH, A, B, C, D, 13, 4, 0x289b7ec6); - OP (FH, D, A, B, C, 0, 11, 0xeaa127fa); - OP (FH, C, D, A, B, 3, 16, 0xd4ef3085); - OP (FH, B, C, D, A, 6, 23, 0x04881d05); - OP (FH, A, B, C, D, 9, 4, 0xd9d4d039); - OP (FH, D, A, B, C, 12, 11, 0xe6db99e5); - OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8); - OP (FH, B, C, D, A, 2, 23, 0xc4ac5665); - - /* Round 4. */ - OP (FI, A, B, C, D, 0, 6, 0xf4292244); - OP (FI, D, A, B, C, 7, 10, 0x432aff97); - OP (FI, C, D, A, B, 14, 15, 0xab9423a7); - OP (FI, B, C, D, A, 5, 21, 0xfc93a039); - OP (FI, A, B, C, D, 12, 6, 0x655b59c3); - OP (FI, D, A, B, C, 3, 10, 0x8f0ccc92); - OP (FI, C, D, A, B, 10, 15, 0xffeff47d); - OP (FI, B, C, D, A, 1, 21, 0x85845dd1); - OP (FI, A, B, C, D, 8, 6, 0x6fa87e4f); - OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0); - OP (FI, C, D, A, B, 6, 15, 0xa3014314); - OP (FI, B, C, D, A, 13, 21, 0x4e0811a1); - OP (FI, A, B, C, D, 4, 6, 0xf7537e82); - OP (FI, D, A, B, C, 11, 10, 0xbd3af235); - OP (FI, C, D, A, B, 2, 15, 0x2ad7d2bb); - OP (FI, B, C, D, A, 9, 21, 0xeb86d391); - - /* Add the starting values of the context. */ - A += A_save; - B += B_save; - C += C_save; - D += D_save; - } - - /* Put checksum in context given as argument. */ - ctx->A = A; - ctx->B = B; - ctx->C = C; - ctx->D = D; -} diff --git a/src/libqof/qof/md5.h b/src/libqof/qof/md5.h deleted file mode 100644 index e501b4363b..0000000000 --- a/src/libqof/qof/md5.h +++ /dev/null @@ -1,163 +0,0 @@ -/* md5.h - Declaration of functions and data types used for MD5 sum - computing library functions. - Copyright (C) 1995, 1996 Free Software Foundation, Inc. - NOTE: The canonical source of this file is maintained with the GNU C - Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu. - - 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, 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, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifndef _MD5_H -#define _MD5_H 1 - -#include -#include - -#if defined HAVE_LIMITS_H || _LIBC -# include -#endif - -/* The following contortions are an attempt to use the C preprocessor - to determine an unsigned integral type that is 32 bits wide. An - alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but - doing that would require that the configure script compile and *run* - the resulting executable. Locally running cross-compiled executables - is usually not possible. */ - -#ifdef _LIBC -# include -typedef u_int32_t md5_uint32; -#else -# if defined __STDC__ && __STDC__ -# define UINT_MAX_32_BITS 4294967295U -# else -# define UINT_MAX_32_BITS 0xFFFFFFFF -# endif - -/* If UINT_MAX isn't defined, assume it's a 32-bit type. - This should be valid for all systems GNU cares about because - that doesn't include 16-bit systems, and only modern systems - (that certainly have ) have 64+-bit integral types. */ - -# ifndef UINT_MAX -# define UINT_MAX UINT_MAX_32_BITS -# endif - -# if UINT_MAX == UINT_MAX_32_BITS -typedef unsigned int md5_uint32; -# else -# if USHRT_MAX == UINT_MAX_32_BITS -typedef unsigned short md5_uint32; -# else -# if ULONG_MAX == UINT_MAX_32_BITS -typedef unsigned long md5_uint32; -# else -/* The following line is intended to evoke an error. - Using #error is not portable enough. */ -"Cannot determine unsigned 32-bit data type." -# endif -# endif -# endif -#endif - -#undef __P -#if defined (__STDC__) && __STDC__ -#define __P(x) x -#else -#define __P(x) () -#endif - -/* Structure to save state of computation between the single steps. */ -struct md5_ctx -{ - md5_uint32 A; - md5_uint32 B; - md5_uint32 C; - md5_uint32 D; - - md5_uint32 total[2]; - md5_uint32 buflen; - char buffer[128]; -}; - -/* - * The following three functions are build up the low level used in - * the functions `md5_stream' and `md5_buffer'. - */ - -/* Initialize structure containing state of computation. - (RFC 1321, 3.3: Step 3) */ -extern void md5_init_ctx __P ((struct md5_ctx *ctx)); - - -/* Starting with the result of former calls of this function (or the - initialization function update the context for the next LEN bytes - starting at BUFFER. - - It is necessary that LEN is a multiple of 64!!! - - IMPORTANT: On some systems it is required that buffer be 32-bit - aligned. */ -extern void md5_process_block __P ((const void *buffer, size_t len, - struct md5_ctx *ctx)); - -/* Starting with the result of former calls of this function (or the - initialization function) update the context for the next LEN bytes - starting at BUFFER. - - It is NOT required that LEN is a multiple of 64. - - IMPORTANT: On some systems it is required that buffer be 32-bit - aligned. */ -extern void md5_process_bytes __P ((const void *buffer, size_t len, - struct md5_ctx *ctx)); - -/* Process the remaining bytes in the buffer and put result from CTX - in first 16 bytes following RESBUF. The result is always in little - endian byte order, so that a byte-wise output yields to the wanted - ASCII representation of the message digest. - - IMPORTANT: On some systems it is required that RESBUF be correctly - aligned for a 32 bits value. */ -extern void *md5_finish_ctx __P ((struct md5_ctx *ctx, void *resbuf)); - - -/* Put result from CTX in first 16 bytes following RESBUF. The result is - always in little endian byte order, so that a byte-wise output yields - to the wanted ASCII representation of the message digest. - - IMPORTANT: On some systems it is required that RESBUF be correctly - aligned for a 32 bits value. */ -extern void *md5_read_ctx __P ((const struct md5_ctx *ctx, void *resbuf)); - - -/* Compute MD5 message digest for bytes read from STREAM. The - resulting message digest number will be written into the 16 bytes - beginning at RESBLOCK. - - IMPORTANT: On some systems it is required that resblock be 32-bit - aligned. */ -extern int md5_stream __P ((FILE *stream, void *resblock)); - - -/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The - result is always in little endian byte order, so that a byte-wise - output yields to the wanted ASCII representation of the message - digest. - - IMPORTANT: On some systems it is required that buffer and resblock - be correctly 32-bit aligned. */ -extern void *md5_buffer __P ((const char *buffer, size_t len, void *resblock)); - -#endif diff --git a/src/libqof/qof/qofinstance.cpp b/src/libqof/qof/qofinstance.cpp index b5ac003554..a8145790d4 100644 --- a/src/libqof/qof/qofinstance.cpp +++ b/src/libqof/qof/qofinstance.cpp @@ -303,7 +303,7 @@ qof_instance_init_data (QofInstance *inst, QofIdType type, QofBook *book) do { - guid_new(&priv->guid); + guid_replace(&priv->guid); if (NULL == qof_collection_lookup_entity (col, &priv->guid)) break; @@ -691,8 +691,9 @@ qof_instance_print_dirty (const QofInstance *inst, gpointer dummy) priv = GET_PRIVATE(inst); if (priv->dirty) { - printf("%s instance %s is dirty.\n", inst->e_type, - guid_to_string(&priv->guid)); + gchar guidstr[GUID_ENCODING_LENGTH+1]; + guid_to_string_buff(&priv->guid, guidstr); + printf("%s instance %s is dirty.\n", inst->e_type, guidstr); } } diff --git a/src/libqof/qof/qofquery.cpp b/src/libqof/qof/qofquery.cpp index fd2528caa1..7d2d0d6f1a 100644 --- a/src/libqof/qof/qofquery.cpp +++ b/src/libqof/qof/qofquery.cpp @@ -1779,9 +1779,9 @@ qof_query_printValueForParam (QofQueryPredData *pd, GString * gs) qof_query_printGuidMatch (pdata->options)); for (node = pdata->guids; node; node = node->next) { - /* THREAD-UNSAFE */ - g_string_append_printf (gs, ", guids: %s", - guid_to_string ((GncGUID *) node->data)); + gchar guidstr[GUID_ENCODING_LENGTH+1]; + guid_to_string_buff ((GncGUID *) node->data,guidstr); + g_string_append_printf (gs, ", guids: %s",guidstr); } return; } diff --git a/src/libqof/qof/qofutil.cpp b/src/libqof/qof/qofutil.cpp index 2990fcea58..2881fd73d8 100644 --- a/src/libqof/qof/qofutil.cpp +++ b/src/libqof/qof/qofutil.cpp @@ -263,7 +263,6 @@ qof_init (void) #endif qof_log_init(); qof_string_cache_init(); - guid_init (); qof_object_initialize (); qof_query_init (); qof_book_register (); @@ -274,7 +273,6 @@ qof_close(void) { qof_query_shutdown (); qof_object_shutdown (); - guid_shutdown (); qof_finalize_backend_libraries(); qof_string_cache_destroy (); qof_log_shutdown(); diff --git a/src/libqof/qof/qofutil.h b/src/libqof/qof/qofutil.h index 3d61f6d179..0bb0a2d1df 100644 --- a/src/libqof/qof/qofutil.h +++ b/src/libqof/qof/qofutil.h @@ -154,15 +154,15 @@ extern "C" /** \brief Initialise the Query Object Framework -Use in place of separate init functions (like guid_init() -and qof_query_init() etc.) to protect against future changes. +Use in place of separate init functions (like qof_query_init(), +etc.) to protect against future changes. */ void qof_init (void); /** \brief Safely close down the Query Object Framework Use in place of separate close / shutdown functions -(like guid_shutdown(), qof_query_shutdown() etc.) to protect +(like qof_query_shutdown(), etc.) to protect against future changes. */ void qof_close (void); diff --git a/src/libqof/qof/test/test-gnc-guid.cpp b/src/libqof/qof/test/test-gnc-guid.cpp index 5369a2168c..2fdda52964 100644 --- a/src/libqof/qof/test/test-gnc-guid.cpp +++ b/src/libqof/qof/test/test-gnc-guid.cpp @@ -47,7 +47,7 @@ static const gchar * suitename {"/qof/gnc-guid"}; static void test_create_gnc_guid (void){ GncGUID * guid {guid_malloc ()}; g_assert (guid != nullptr); - guid_new (guid); + guid_replace (guid); /*We apparently don't need to free guid_null (based on its being const)*/ const GncGUID * guidnull {guid_null ()}; g_assert (!guid_equal (guid, guidnull)); @@ -58,7 +58,7 @@ static void test_create_gnc_guid (void){ static void test_gnc_guid_copy (void) { GncGUID * guid {guid_malloc ()}; g_assert (guid != nullptr); - guid_new (guid); + guid_replace (guid); GncGUID * cp {guid_copy (guid)}; g_assert (guid_equal (guid, cp)); guid_free (cp); @@ -69,16 +69,17 @@ static void test_gnc_guid_copy (void) { defined in the guid api. We then compare them.*/ static void test_gnc_guid_to_string (void) { GncGUID * guid {guid_malloc()}; + gchar guidstrp [GUID_ENCODING_LENGTH+1]; + gchar guidstrp2[GUID_ENCODING_LENGTH+1]; g_assert (guid != nullptr); - guid_new (guid); + guid_replace (guid); string message {" using guid_to_string (deprecated): "}; - /*don't free the return value of guid_to_string!*/ - string guidstr {guid_to_string (guid)}; + guid_to_string_buff (guid,guidstrp); + string guidstr {guidstrp}; g_assert (guidstr.size () == GUID_ENCODING_LENGTH); message += guidstr; g_test_message ("%s", message.c_str ()); message = " using guid_to_string_buff: "; - gchar guidstrp2 [GUID_ENCODING_LENGTH+1]; gchar * ret {guid_to_string_buff (guid, guidstrp2)}; g_assert (ret == guidstrp2 + GUID_ENCODING_LENGTH); string guidstr2 {guidstrp2}; @@ -135,7 +136,7 @@ static void test_gnc_guid_roundtrip (void) { g_assert (guid1 != nullptr); GncGUID * guid2 {guid_malloc ()}; g_assert (guid2 != nullptr); - guid_new (guid1); + guid_replace (guid1); gchar guidstrp [GUID_ENCODING_LENGTH+1]; gchar * temp {guid_to_string_buff (guid1, guidstrp)}; @@ -147,14 +148,52 @@ static void test_gnc_guid_roundtrip (void) { guid_free (guid1); } +/** + * guid_replace should put a newly generated guid into the parameter. In + * this test, we ensure that the first "new" guid doesn't match a subsequent + * "new" guid in the same memory location. + */ +static void test_gnc_guid_replace (void) +{ + GncGUID * guid1 {guid_malloc ()}; + + guid_replace (guid1); + GncGUID * guid2 {guid_copy (guid1)}; + guid_replace (guid1); + g_assert (! guid_equal (guid1, guid2)); + + guid_free (guid2); + guid_free (guid1); +} + +/** + * We create a bogus guid and ensure that it doesn't get parsed successfully, + * then we pass in a good GUID from string and ensure that the function returns true. + */ +static void test_gnc_guid_from_string (void) { + GncGUID * guid {guid_malloc ()}; + const char * bogus {"01-23-45-6789a.cDeF0123z56789abcdef"}; + + /* string_to_guid should return false if either parameter is null*/ + g_assert (!string_to_guid (nullptr, guid)); + g_assert (!string_to_guid (bogus, nullptr)); + + g_assert (!string_to_guid (bogus, guid)); + + const char * good {"0123456789abcdef1234567890abcdef"}; + g_assert (string_to_guid (good, guid)); + + guid_free (guid); +} + void test_suite_gnc_guid (void) { - guid_init (); GNC_TEST_ADD_FUNC (suitename, "gnc create guid", test_create_gnc_guid); GNC_TEST_ADD_FUNC (suitename, "gnc copy guid", test_gnc_guid_copy); GNC_TEST_ADD_FUNC (suitename, "gnc guid to string", test_gnc_guid_to_string); GNC_TEST_ADD_FUNC (suitename, "gnc guid equal", test_gnc_guid_equals); GNC_TEST_ADD_FUNC (suitename, "gnc guid string roundtrip", test_gnc_guid_roundtrip); - guid_shutdown (); + GNC_TEST_ADD_FUNC (suitename, "gnc guid from string", test_gnc_guid_from_string); + GNC_TEST_ADD_FUNC (suitename, "gnc guid replace", test_gnc_guid_replace); } diff --git a/src/libqof/qof/test/test-kvp_frame.c b/src/libqof/qof/test/test-kvp_frame.c index ce356375c5..d17306574a 100644 --- a/src/libqof/qof/test/test-kvp_frame.c +++ b/src/libqof/qof/test/test-kvp_frame.c @@ -101,8 +101,7 @@ populate_frame (KvpFrame *frame) ts.tv_sec = 1; ts.tv_nsec = 1; - guid = guid_malloc (); - guid_new (guid); + guid = guid_new (); g_date_set_dmy (&gdate, 26, 1, 1957); kvp_frame_set_gint64( frame, "gint64-type", 100 ); @@ -163,8 +162,7 @@ test_kvp_frame_copy( Fixture *fixture, gconstpointer pData ) test_ts.tv_sec = 1; test_ts.tv_nsec = 1; test_str = "abcdefghijklmnop"; - test_guid = guid_malloc(); - guid_new( test_guid ); + test_guid = guid_new(); test_frame = kvp_frame_new(); g_assert( fixture->frame ); @@ -223,8 +221,7 @@ test_kvp_frame_set_foo( Fixture *fixture, gconstpointer pData ) test_gnc_numeric = gnc_numeric_zero(); test_ts.tv_sec = 1; test_ts.tv_nsec = 1; - test_guid = guid_malloc(); - guid_new( test_guid ); + test_guid = guid_new(); g_assert( fixture->frame ); g_assert( kvp_frame_is_empty( fixture->frame ) ); @@ -512,8 +509,7 @@ test_kvp_value_copy( void ) KvpFrame *frame_orig, *frame_copy; gnc_numeric_orig = gnc_numeric_zero(); - guid_orig = guid_malloc(); - guid_new( guid_orig ); + guid_orig = guid_new(); ts_orig.tv_sec = 1; ts_orig.tv_nsec = 1; list_orig = NULL; @@ -631,8 +627,7 @@ test_kvp_glist_copy( void ) KvpFrame *frame_orig; gnc_numeric_orig = gnc_numeric_zero(); - guid_orig = guid_malloc(); - guid_new( guid_orig ); + guid_orig = guid_new(); ts_orig.tv_sec = 1; ts_orig.tv_nsec = 1; list_orig = NULL; @@ -703,8 +698,7 @@ test_kvp_glist_compare( void ) KvpFrame *frame_orig; gnc_numeric_orig = gnc_numeric_zero(); - guid_orig = guid_malloc(); - guid_new( guid_orig ); + guid_orig = guid_new(); ts_orig.tv_sec = 1; ts_orig.tv_nsec = 1; list_orig = NULL; @@ -797,10 +791,8 @@ test_kvp_value_compare( void ) gnc_numeric_orig = gnc_numeric_zero(); gnc_numeric_copy = gnc_numeric_zero(); - guid_orig = guid_malloc(); - guid_new( guid_orig ); - guid_copy = guid_malloc(); - guid_new( guid_copy ); + guid_orig = guid_new(); + guid_copy = guid_new(); ts_orig.tv_sec = 1; ts_orig.tv_nsec = 1; ts_copy.tv_sec = 2; @@ -988,7 +980,7 @@ test_binary_to_string( void ) static void test_kvp_value_to_string( void ) { - const gchar *str_tmp; + gchar guidstr[GUID_ENCODING_LENGTH+1]; gchar *str_tmp2, *str_tmp3; gchar *result; KvpValue *gint64_value; @@ -1007,8 +999,7 @@ test_kvp_value_to_string( void ) KvpFrame *frame_orig; gnc_numeric_orig = gnc_numeric_zero(); - guid_orig = guid_malloc(); - guid_new( guid_orig ); + guid_orig = guid_new(); ts_orig.tv_sec = 1; ts_orig.tv_nsec = 1; list_orig = NULL; @@ -1047,8 +1038,8 @@ test_kvp_value_to_string( void ) result = kvp_value_to_string( guid_value ); g_assert( result ); - str_tmp = guid_to_string( kvp_value_get_guid( guid_value ) ); - str_tmp2 = g_strdup_printf("KVP_VALUE_GUID(%s)", str_tmp ? str_tmp : ""); + guid_to_string_buff( kvp_value_get_guid( guid_value ), guidstr); + str_tmp2 = g_strdup_printf("KVP_VALUE_GUID(%s)", guidstr); g_assert_cmpstr( result, == , str_tmp2 ); g_free( result ); g_free( str_tmp2 ); @@ -1093,8 +1084,7 @@ test_kvp_frame_to_string( Fixture *fixture, gconstpointer pData ) KvpFrame *test_frame; test_gnc_numeric = gnc_numeric_zero(); - test_guid = guid_malloc(); - guid_new( test_guid ); + test_guid = guid_new(); test_ts.tv_sec = 1; test_ts.tv_nsec = 1; test_frame = kvp_frame_new(); diff --git a/src/libqof/qof/test/test-qofinstance.c b/src/libqof/qof/test/test-qofinstance.c index a47a8adda0..b6b317f983 100644 --- a/src/libqof/qof/test/test-qofinstance.c +++ b/src/libqof/qof/test/test-qofinstance.c @@ -97,8 +97,7 @@ test_instance_set_get_guid( Fixture *fixture, gconstpointer pData ) g_assert( qof_entity_get_guid( NULL ) == guid_null() ); /* set up */ - gncGuid = guid_malloc(); - guid_new( gncGuid ); + gncGuid = guid_new(); g_assert( QOF_IS_INSTANCE( fixture->inst ) ); g_assert( gncGuid );