gnucash master: Multiple changes pushed

John Ralls jralls at code.gnucash.org
Thu Aug 7 16:26:26 EDT 2014


Updated	 via  https://github.com/Gnucash/gnucash/commit/d20dcb46 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/95925126 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/4e7e52a3 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/e4d97f6d (commit)
	 via  https://github.com/Gnucash/gnucash/commit/551e5c60 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/c286448f (commit)
	 via  https://github.com/Gnucash/gnucash/commit/46455c75 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/321a159a (commit)
	 via  https://github.com/Gnucash/gnucash/commit/b465fef9 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/56af86c0 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/163acb86 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/1e5b14b5 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/28e1d1a8 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/c146e210 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/9711ae24 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/726ab02d (commit)
	 via  https://github.com/Gnucash/gnucash/commit/ce94872e (commit)
	 via  https://github.com/Gnucash/gnucash/commit/cbc292cc (commit)
	 via  https://github.com/Gnucash/gnucash/commit/f40a93c6 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/30fac05e (commit)
	 via  https://github.com/Gnucash/gnucash/commit/2a408ab9 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/9c82a1e9 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/26a49f96 (commit)
	from  https://github.com/Gnucash/gnucash/commit/d5fa5486 (commit)



commit d20dcb46486a90d1864f11250428df51ec9a1ae8
Merge: 9592512 163acb8
Author: John Ralls <jralls at ceridwen.us>
Date:   Thu Aug 7 13:09:57 2014 -0700

    Merge branch 'guidcpp'
    
    Incorporate Aaron Laws's reimplementation of gncguid with boost::guid.


commit 959251265ac922d55719f1f34cf12a8cebb53f5b
Author: John Ralls <jralls at ceridwen.us>
Date:   Mon Aug 4 14:18:39 2014 -0700

    Add gnc-date.cpp to POTFILES.in
    
    Because make check complained. Dunno what changed...

diff --git a/po/POTFILES.in b/po/POTFILES.in
index a52fdea..7348c73 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -502,6 +502,7 @@ src/report/utility-reports/gncmod-utility-reports.c
 src/tax/us/gncmod-tax-us.c
 src/gnome/gnucash.appdata.xml.in
 src/gnome/gnucash.desktop.in.in
+src/libqof/qof/gnc-date.cpp
 src/libqof/qof/qofbookslots.h
 intl-scm/guile-strings.c
 doc/tip_of_the_day.list.in

commit 4e7e52a31167ec108ffcd73b22438a4245131b0d
Merge: d5fa548 e4d97f6
Author: John Ralls <jralls at ceridwen.us>
Date:   Thu Aug 7 11:47:27 2014 -0700

    Merge branch 'maint'


commit e4d97f6d7466f1c0bd74785bf5cc450f08c794ba
Author: John Ralls <jralls at ceridwen.us>
Date:   Thu Aug 7 11:46:17 2014 -0700

    Fix test-backend-dbi segfault with libdbi-0.9.0.
    
    dbi_inst must be initialized before it can be used.

diff --git a/src/backend/dbi/test/test-backend-dbi-basic.c b/src/backend/dbi/test/test-backend-dbi-basic.c
index d7e88eb..b3203f0 100644
--- a/src/backend/dbi/test/test-backend-dbi-basic.c
+++ b/src/backend/dbi/test/test-backend-dbi-basic.c
@@ -36,7 +36,7 @@
 
 #if LIBDBI_VERSION >= 900
 #define HAVE_LIBDBI_R 1
-static dbi_inst dbi_instance;
+static dbi_inst dbi_instance = NULL;
 #else
 #define HAVE_LIBDBI_R 0
 #endif
@@ -597,8 +597,11 @@ test_suite_gnc_backend_dbi (void)
     dbi_driver driver = NULL;
     GList *drivers = NULL;
     #if HAVE_LIBDBI_R
+    if (dbi_instance == NULL)
+      dbi_initialize_r (NULL, &dbi_instance);
     while ((driver = dbi_driver_list_r (driver, dbi_instance)))
     #else
+    dbi_initialize (NULL);
     while ((driver = dbi_driver_list (driver)))
     #endif
     {

commit 551e5c6093f22aeee29561cae1f4c34150e5d093
Author: John Ralls <jralls at ceridwen.us>
Date:   Thu Aug 7 11:45:40 2014 -0700

    Fix uninitialized variable warning.

diff --git a/src/plugins/bi_import/dialog-bi-import.c b/src/plugins/bi_import/dialog-bi-import.c
index 8c77779..05ef930 100644
--- a/src/plugins/bi_import/dialog-bi-import.c
+++ b/src/plugins/bi_import/dialog-bi-import.c
@@ -528,7 +528,7 @@ gnc_bi_import_create_bis (GtkListStore * store, QofBook * book,
     Timespec today;
     InvoiceWindow *iw;
     gchar *new_id = NULL;
- 	gint64  	denom;
+    gint64 denom = 0;
     gnc_commodity *currency;
     
     // these arguments are needed

commit c286448fdb6f9cbbbff42f2ab73f5291168111f1
Author: John Ralls <jralls at ceridwen.us>
Date:   Thu Aug 7 11:41:21 2014 -0700

    Add note about automake 1.14 to configure.ac
    
    The note has the details, but I wasn't able to get gnucash to build with
    automake 1.14 without passing --disable-dependency-tracking regardless of
    whether I used the subdir-objects option. If I could figure out a good way
    to poison configure with automake 1.14 I would.

diff --git a/configure.ac b/configure.ac
index bb07382..92b3b4c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -33,7 +33,15 @@ GNUCASH_NANO_VERSION=0
 #storage-compatible with the current version. See the comments in
 #src/backend/dbi/gnc-backend-dbi.c:gnc_dbi_load.
 GNUCASH_RESAVE_VERSION=19920
-# Initialize automake -- make sure we have at least version 1.9
+# Initialize automake -- make sure we have at least version 1.9 Note:
+# Automake 1.14 issues a ton of warnings about subdir-objects, which
+# will become the default in automake 2.0; unfortunately this option
+# is broken and prevents building without passing
+# --disable-dependency-tracking to configure, which make-distcheck
+# doesn't do. See
+# http://lists.gnu.org/archive/html/automake/2014-04/msg00002.html and
+# http://debbugs.gnu.org/cgi/bugreport.cgi?bug=13928 for details.
+# In the meantime the best option is to use Automake 1.13 or earlier.
 AM_INIT_AUTOMAKE([1.9 dist-bzip2])
 
 # Parse out the version number

commit 46455c75185f4ac04922dc6ab7f8b8094e55b9c9
Author: John Ralls <jralls at ceridwen.us>
Date:   Thu Aug 7 10:23:50 2014 -0700

    Revert "Fix broken test-backend-dbi with libdbi 0.9."
    
    This reverts commit 321a159af29a9b51fe793c2528dccb74b0443bf9.
    Got two unrelated changes into a single changeset.

diff --git a/configure.ac b/configure.ac
index 2f70fc5..bb07382 100644
--- a/configure.ac
+++ b/configure.ac
@@ -34,7 +34,7 @@ GNUCASH_NANO_VERSION=0
 #src/backend/dbi/gnc-backend-dbi.c:gnc_dbi_load.
 GNUCASH_RESAVE_VERSION=19920
 # Initialize automake -- make sure we have at least version 1.9
-AM_INIT_AUTOMAKE([1.9 dist-bzip2 subdir-objects])
+AM_INIT_AUTOMAKE([1.9 dist-bzip2])
 
 # Parse out the version number
 GNUCASH_VERSION_STRING=AC_PACKAGE_VERSION
diff --git a/src/backend/dbi/test/test-backend-dbi-basic.c b/src/backend/dbi/test/test-backend-dbi-basic.c
index b3203f0..d7e88eb 100644
--- a/src/backend/dbi/test/test-backend-dbi-basic.c
+++ b/src/backend/dbi/test/test-backend-dbi-basic.c
@@ -36,7 +36,7 @@
 
 #if LIBDBI_VERSION >= 900
 #define HAVE_LIBDBI_R 1
-static dbi_inst dbi_instance = NULL;
+static dbi_inst dbi_instance;
 #else
 #define HAVE_LIBDBI_R 0
 #endif
@@ -597,11 +597,8 @@ test_suite_gnc_backend_dbi (void)
     dbi_driver driver = NULL;
     GList *drivers = NULL;
     #if HAVE_LIBDBI_R
-    if (dbi_instance == NULL)
-      dbi_initialize_r (NULL, &dbi_instance);
     while ((driver = dbi_driver_list_r (driver, dbi_instance)))
     #else
-    dbi_initialize (NULL);
     while ((driver = dbi_driver_list (driver)))
     #endif
     {

commit 321a159af29a9b51fe793c2528dccb74b0443bf9
Author: John Ralls <jralls at ceridwen.us>
Date:   Thu Aug 7 10:00:39 2014 -0700

    Fix broken test-backend-dbi with libdbi 0.9.
    
    Segfaulted for an uninitialized dbi_instance.

diff --git a/configure.ac b/configure.ac
index bb07382..2f70fc5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -34,7 +34,7 @@ GNUCASH_NANO_VERSION=0
 #src/backend/dbi/gnc-backend-dbi.c:gnc_dbi_load.
 GNUCASH_RESAVE_VERSION=19920
 # Initialize automake -- make sure we have at least version 1.9
-AM_INIT_AUTOMAKE([1.9 dist-bzip2])
+AM_INIT_AUTOMAKE([1.9 dist-bzip2 subdir-objects])
 
 # Parse out the version number
 GNUCASH_VERSION_STRING=AC_PACKAGE_VERSION
diff --git a/src/backend/dbi/test/test-backend-dbi-basic.c b/src/backend/dbi/test/test-backend-dbi-basic.c
index d7e88eb..b3203f0 100644
--- a/src/backend/dbi/test/test-backend-dbi-basic.c
+++ b/src/backend/dbi/test/test-backend-dbi-basic.c
@@ -36,7 +36,7 @@
 
 #if LIBDBI_VERSION >= 900
 #define HAVE_LIBDBI_R 1
-static dbi_inst dbi_instance;
+static dbi_inst dbi_instance = NULL;
 #else
 #define HAVE_LIBDBI_R 0
 #endif
@@ -597,8 +597,11 @@ test_suite_gnc_backend_dbi (void)
     dbi_driver driver = NULL;
     GList *drivers = NULL;
     #if HAVE_LIBDBI_R
+    if (dbi_instance == NULL)
+      dbi_initialize_r (NULL, &dbi_instance);
     while ((driver = dbi_driver_list_r (driver, dbi_instance)))
     #else
+    dbi_initialize (NULL);
     while ((driver = dbi_driver_list (driver)))
     #endif
     {

commit b465fef9ac9ad615a5a90018dec685a3379ff03b
Author: Mike Evans <mikee at millstreamcomputing.co.uk>
Date:   Thu Aug 7 16:00:38 2014 +0100

    Bug 734183 - Set all of the denominators correctly on the currency values.

diff --git a/src/plugins/bi_import/dialog-bi-import.c b/src/plugins/bi_import/dialog-bi-import.c
index 9d31961..8c77779 100644
--- a/src/plugins/bi_import/dialog-bi-import.c
+++ b/src/plugins/bi_import/dialog-bi-import.c
@@ -520,7 +520,7 @@ gnc_bi_import_create_bis (GtkListStore * store, QofBook * book,
     GncInvoice *invoice;
     GncEntry *entry;
     gint day, month, year;
-    gnc_numeric n;
+    gnc_numeric value;
     GncOwner *owner;
     Account *acc;
     enum update {YES = GTK_RESPONSE_YES, NO = GTK_RESPONSE_NO} update;
@@ -528,7 +528,9 @@ gnc_bi_import_create_bis (GtkListStore * store, QofBook * book,
     Timespec today;
     InvoiceWindow *iw;
     gchar *new_id = NULL;
-
+ 	gint64  	denom;
+    gnc_commodity *currency;
+    
     // these arguments are needed
     g_return_if_fail (store && book);
     // logic of this function only works for bills or invoices
@@ -693,6 +695,9 @@ gnc_bi_import_create_bis (GtkListStore * store, QofBook * book,
 
         // add entry to invoice/bill
         entry = gncEntryCreate (book);
+        gncEntryBeginEdit(entry);
+        currency = gncInvoiceGetCurrency(invoice);
+        if (currency) denom = gnc_commodity_get_fraction(currency);
         // FIXME: Must check for the return value of qof_scan_date!
         qof_scan_date (date, &day, &month, &year);
         {
@@ -705,42 +710,39 @@ gnc_bi_import_create_bis (GtkListStore * store, QofBook * book,
         gncEntrySetDescription (entry, desc);
         gncEntrySetAction (entry, action);
 
-        n = gnc_numeric_zero ();
-        gnc_exp_parser_parse (quantity, &n, NULL);
-        gncEntrySetQuantity (entry, n);
+        gnc_exp_parser_parse (quantity, &value, NULL);
+        gncEntrySetQuantity (entry, value);
         acc = gnc_account_lookup_for_register (gnc_get_current_root_account (),
                                                account);
         
         if (g_ascii_strcasecmp (type, "BILL") == 0)
         {
             gncEntrySetBillAccount (entry, acc);
-            n = gnc_numeric_zero ();
-            gnc_exp_parser_parse (price, &n, NULL);
-            gncEntrySetBillPrice (entry, n);
+            gnc_exp_parser_parse (price, &value, NULL);
+            value = gnc_numeric_convert (value, denom, GNC_HOW_RND_NEVER);
+            gncEntrySetBillPrice (entry, value);
             gncEntrySetBillTaxable (entry, text2bool (taxable));
             gncEntrySetBillTaxIncluded (entry, text2bool (taxincluded));
-            gncEntrySetBillTaxTable (entry,
-                                     gncTaxTableLookupByName (book, tax_table));
-            n = gnc_numeric_zero ();
-            gnc_exp_parser_parse (discount, &n, NULL);
+            gncEntrySetBillTaxTable (entry, gncTaxTableLookupByName (book, tax_table));
+            gncEntryCommitEdit(entry);
             gncBillAddEntry (invoice, entry);
         }
         else if (g_ascii_strcasecmp (type, "INVOICE") == 0)
         {
             gncEntrySetNotes (entry, notes);
             gncEntrySetInvAccount (entry, acc);
-            n = gnc_numeric_zero ();
-            gnc_exp_parser_parse (price, &n, NULL);
-            gncEntrySetInvPrice (entry, n);
+            gnc_exp_parser_parse (price, &value, NULL);
+            value = gnc_numeric_convert (value, denom, GNC_HOW_RND_NEVER);
+            gncEntrySetInvPrice (entry, value);
             gncEntrySetInvTaxable (entry, text2bool (taxable));
             gncEntrySetInvTaxIncluded (entry, text2bool (taxincluded));
-            gncEntrySetInvTaxTable (entry,
-                                    gncTaxTableLookupByName (book, tax_table));
-            n = gnc_numeric_zero ();
-            gnc_exp_parser_parse (discount, &n, NULL);
-            gncEntrySetInvDiscount (entry, n);
+            gncEntrySetInvTaxTable (entry, gncTaxTableLookupByName (book, tax_table));
+            gnc_exp_parser_parse (discount, &value, NULL);
+            value = gnc_numeric_convert (value, denom, GNC_HOW_RND_NEVER);
+            gncEntrySetInvDiscount (entry, value);
             gncEntrySetInvDiscountType (entry, text2disc_type (disc_type));
             gncEntrySetInvDiscountHow (entry, text2disc_how (disc_how));
+            gncEntryCommitEdit(entry);
             gncInvoiceAddEntry (invoice, entry);
         }
         valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter);

commit 56af86c0a27cf07e5740c63dba1fdf3a69a2d549
Author: Mike Evans <mikee at millstreamcomputing.co.uk>
Date:   Sun Aug 3 14:51:06 2014 +0100

    Bill invoice importer crashing when invoice has multiple lines.
    
    Move the final g_free(s) outside the while loop.

diff --git a/src/plugins/bi_import/dialog-bi-import.c b/src/plugins/bi_import/dialog-bi-import.c
index ad91f55..9d31961 100644
--- a/src/plugins/bi_import/dialog-bi-import.c
+++ b/src/plugins/bi_import/dialog-bi-import.c
@@ -777,31 +777,32 @@ gnc_bi_import_create_bis (GtkListStore * store, QofBook * book,
             }
 
         }
-        g_free (new_id);
         
-
-        // cleanup
-        g_free (id);
-        g_free (date_opened);
-        g_free (owner_id);
-        g_free (billing_id);
-        g_free (notes);
-        g_free (date);
-        g_free (desc);
-        g_free (action);
-        g_free (account);
-        g_free (quantity);
-        g_free (price);
-        g_free (disc_type);
-        g_free (disc_how);
-        g_free (discount);
-        g_free (taxable);
-        g_free (taxincluded);
-        g_free (tax_table);
-        g_free (date_posted);
-        g_free (due_date);
-        g_free (account_posted);
-        g_free (memo_posted);
-        g_free (accumulatesplits);
+        
     }
+    // cleanup
+    g_free (new_id);
+    g_free (id);
+    g_free (date_opened);
+    g_free (owner_id);
+    g_free (billing_id);
+    g_free (notes);
+    g_free (date);
+    g_free (desc);
+    g_free (action);
+    g_free (account);
+    g_free (quantity);
+    g_free (price);
+    g_free (disc_type);
+    g_free (disc_how);
+    g_free (discount);
+    g_free (taxable);
+    g_free (taxincluded);
+    g_free (tax_table);
+    g_free (date_posted);
+    g_free (due_date);
+    g_free (account_posted);
+    g_free (memo_posted);
+    g_free (accumulatesplits);
+    
 }

commit 163acb863d4a97bf94d61528f4a9819c4524a665
Author: John Ralls <jralls at ceridwen.us>
Date:   Mon Aug 4 15:06:02 2014 -0700

    Two minor tweaks to pass make check.

diff --git a/po/POTFILES.in b/po/POTFILES.in
index 7348c73..29d133b 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -426,7 +426,6 @@ src/import-export/qif-imp/gncmod-qif-import.c
 src/import-export/qif/qif-context.c
 src/import-export/qif/qif-file.c
 src/import-export/qif/qif-objects.c
-src/libqof/qof/md5.c
 src/plugins/bi_import/dialog-bi-import-gui.c
 src/plugins/bi_import/dialog-bi-import-helper.c
 src/plugins/bi_import/dialog-bi-import.c
diff --git a/src/libqof/qof/guid.cpp b/src/libqof/qof/guid.cpp
index 73b913a..d434543 100644
--- a/src/libqof/qof/guid.cpp
+++ b/src/libqof/qof/guid.cpp
@@ -85,7 +85,7 @@ gnc_value_get_guid (const GValue *value)
     return val;
 }
 
-static GncGUID * nullguid {reinterpret_cast<GncGUID*> (new boost::uuids::uuid{0})};
+static GncGUID * nullguid {reinterpret_cast<GncGUID*> (new boost::uuids::uuid{{0}})};
 
 /*It looks like we are expected to provide the same pointer every time from this function*/
 const GncGUID *

commit 1e5b14b54f49d7ab7f74a800de7266001ad91964
Merge: 28e1d1a 9711ae2
Author: John Ralls <jralls at ceridwen.us>
Date:   Mon Aug 4 14:35:23 2014 -0700

    Merge branch 'guidcpp' of https://github.com/limitedAtonement/gnucash
    
    into guidcpp


commit 28e1d1a8c2782826c9b09d4e8d3b935d759ddb19
Author: John Ralls <jralls at ceridwen.us>
Date:   Mon Aug 4 14:18:39 2014 -0700

    Add gnc-date.cpp to POTFILES.in
    
    Because make check complained. Dunno what changed...

diff --git a/po/POTFILES.in b/po/POTFILES.in
index a52fdea..7348c73 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -502,6 +502,7 @@ src/report/utility-reports/gncmod-utility-reports.c
 src/tax/us/gncmod-tax-us.c
 src/gnome/gnucash.appdata.xml.in
 src/gnome/gnucash.desktop.in.in
+src/libqof/qof/gnc-date.cpp
 src/libqof/qof/qofbookslots.h
 intl-scm/guile-strings.c
 doc/tip_of_the_day.list.in

commit c146e210438b5878374aadd6be9f413ebf66e65d
Author: John Ralls <jralls at ceridwen.us>
Date:   Mon Aug 4 14:09:22 2014 -0700

    Replace built-in md5 hashing with GChecksum
    
    Prepare for removing it when we replace the GncGUID implementation with Boost.

diff --git a/src/import-export/aqb/gnc-gwen-gui.c b/src/import-export/aqb/gnc-gwen-gui.c
index 9cf6481..95af31c 100644
--- a/src/import-export/aqb/gnc-gwen-gui.c
+++ b/src/import-export/aqb/gnc-gwen-gui.c
@@ -43,7 +43,6 @@
 #include "gnc-prefs.h"
 #include "gnc-ui.h"
 #include "gnc-plugin-aqbanking.h"
-#include "md5.h"
 #include "qof.h"
 
 #if GWENHYWFAR_VERSION_INT >= 39921
@@ -1492,10 +1491,10 @@ checkcert_cb(GWEN_GUI *gwen_gui, const GWEN_SSLCERTDESCR *cert,
 {
     GncGWENGui *gui = GETDATA_GUI(gwen_gui);
     const gchar *hash, *status;
-    struct md5_ctx md5_context;
+    GChecksum *gcheck = g_checksum_new (G_CHECKSUM_MD5);
     gchar cert_hash[16];
-    gchar *cert_hash_hex;
     gint retval, i;
+    gsize hashlen = 0;
 
     g_return_val_if_fail(gui && gui->accepted_certs, -1);
 
@@ -1504,25 +1503,19 @@ checkcert_cb(GWEN_GUI *gwen_gui, const GWEN_SSLCERTDESCR *cert,
     hash = GWEN_SslCertDescr_GetFingerPrint(cert);
     status = GWEN_SslCertDescr_GetStatusText(cert);
 
-    /* Operate on an md5sum of the pair of hash and status */
-    md5_init_ctx(&md5_context);
-    md5_process_bytes(hash, strlen(hash), &md5_context);
-    md5_process_bytes(status, strlen(status), &md5_context);
-    md5_finish_ctx(&md5_context, cert_hash);
+    g_checksum_update (gcheck, hash, strlen (hash));
+    g_checksum_update (gcheck, status, strlen (status));
 
     /* Did we get the permanently accepted certs from AqBanking? */
     if (gui->permanently_accepted_certs)
     {
         /* Generate a hex string of the cert_hash for usage by AqBanking cert store */
-        cert_hash_hex = g_new0(gchar, 33);
-        for (i = 0; i < 16; i++)
-            g_snprintf(cert_hash_hex + 2 * i, 3, "%02X", (unsigned char)cert_hash[i]);
-
-        retval = GWEN_DB_GetIntValue(gui->permanently_accepted_certs, cert_hash_hex, 0, -1);
-        g_free(cert_hash_hex);
+        retval = GWEN_DB_GetIntValue(gui->permanently_accepted_certs,
+				     g_checksum_get_string (gcheck), 0, -1);
         if (retval == 0)
         {
             /* Certificate is marked as accepted in AqBanking's cert store */
+	    g_checksum_free (gcheck);
             LEAVE("Certificate accepted by AqBanking's permanent cert store");
             return 0;
         }
@@ -1532,6 +1525,10 @@ checkcert_cb(GWEN_GUI *gwen_gui, const GWEN_SSLCERTDESCR *cert,
         g_warning("Can't check permanently accepted certs from invalid AqBanking cert store.");
     }
 
+    g_checksum_get_digest (gcheck, cert_hash, &hashlen);
+    g_checksum_free (gcheck);
+    g_assert (hashlen <= sizeof (cert_hash));
+
     if (g_hash_table_lookup(gui->accepted_certs, cert_hash))
     {
         /* Certificate has been accepted by Gnucash before */

commit 9711ae244664bb5b6fb2f85bcafcfb526ca2c7a0
Author: lmat <dartme18 at gmail.com>
Date:   Wed Jul 30 11:57:36 2014 -0400

    Added new tests.
    
    Added tests for string_to_guid and guid_replace.

diff --git a/src/libqof/qof/test/test-gnc-guid.cpp b/src/libqof/qof/test/test-gnc-guid.cpp
index bebd5c9..2fdda52 100644
--- a/src/libqof/qof/test/test-gnc-guid.cpp
+++ b/src/libqof/qof/test/test-gnc-guid.cpp
@@ -148,6 +148,44 @@ 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)
 {
     GNC_TEST_ADD_FUNC (suitename, "gnc create guid", test_create_gnc_guid);
@@ -155,5 +193,7 @@ void test_suite_gnc_guid (void)
     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);
+    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);
 }
 

commit 726ab02d651e10c520dba895d368b0760f3396e2
Author: lmat <dartme18 at gmail.com>
Date:   Mon Jul 28 17:03:07 2014 -0400

    Simplified some of the GUID code.
    
    This change applies some recommendations from jralls. It better utilizes for loops,
    and usage of swap. We also try to make sure the null guid is not freed since it's
    reused, and catch a c++ exception to make sure it doens't escape into C code when
    parsing a GUID.

diff --git a/src/libqof/qof/guid.cpp b/src/libqof/qof/guid.cpp
index 4fda852..73b913a 100644
--- a/src/libqof/qof/guid.cpp
+++ b/src/libqof/qof/guid.cpp
@@ -85,6 +85,15 @@ gnc_value_get_guid (const GValue *value)
     return val;
 }
 
+static GncGUID * nullguid {reinterpret_cast<GncGUID*> (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 *
@@ -99,7 +108,11 @@ guid_free (GncGUID *guid)
 {
     if (!guid)
         return;
+    if (guid == nullguid)
+        /*!!Don't delete that!!*/
+        return;
     delete reinterpret_cast<boost::uuids::uuid*> (guid);
+    guid = nullptr;
 }
 
 
@@ -111,23 +124,15 @@ guid_copy (const GncGUID *guid)
     return reinterpret_cast<GncGUID*> (ret);
 }
 
-static GncGUID * nullguid {reinterpret_cast<GncGUID*> (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;
-}
-
 /*Takes an allocated guid pointer and constructs it in place*/
 void
 guid_replace (GncGUID *guid)
 {
     static boost::uuids::random_generator gen;
     boost::uuids::uuid * val {reinterpret_cast<boost::uuids::uuid*> (guid)};
-    val->boost::uuids::uuid::~uuid();
-    new (val) boost::uuids::uuid (gen ());
+    val->boost::uuids::uuid::~uuid ();
+    boost::uuids::uuid temp (gen ());
+    val->swap (temp);
 }
 
 GncGUID *
@@ -169,25 +174,13 @@ guid_to_string_buff (const GncGUID * guid, gchar *str)
 {
     if (!str || !guid) return NULL;
 
-    static boost::uuids::string_generator str_gen;
-    stringstream ostr;
-    boost::uuids::uuid const & tempg = *reinterpret_cast<boost::uuids::uuid const *>(guid);
-    ostr << tempg;
-    string const & val (ostr.str());
-    /*unsigned size {val.size()};
-     size must equal GUID_ENCODING_LENGTH*/
-    unsigned stringspot{0};
-    for (unsigned destspot{0}; destspot < GUID_ENCODING_LENGTH; ++destspot, ++stringspot){
-        switch (stringspot){
-            /*there are hyphens in boost's output, and we need to skip them in our output*/
-            case 8:
-            case 13:
-            case 18:
-            case 23:
-                ++stringspot;
-        }
-        str[destspot] = val[stringspot];
-    }
+    boost::uuids::uuid const & tempg = *reinterpret_cast<boost::uuids::uuid const *> (guid);
+    unsigned destspot {0};
+    string const & val {to_string (tempg)};
+    for (auto val_char : val)
+        if (val_char != '-')
+            str [destspot++] = val_char;
+
     str[GUID_ENCODING_LENGTH] = '\0';
     return &str[GUID_ENCODING_LENGTH];
 }
@@ -195,9 +188,19 @@ guid_to_string_buff (const GncGUID * guid, gchar *str)
 gboolean
 string_to_guid (const char * str, GncGUID * guid)
 {
-    static boost::uuids::string_generator strgen;
-    boost::uuids::uuid * converted {reinterpret_cast<boost::uuids::uuid*> (guid)};
-    new (converted) boost::uuids::uuid (strgen (str));
+    if (!guid || !str)
+        return false;
+
+    try 
+    {
+        static boost::uuids::string_generator strgen;
+        boost::uuids::uuid * converted {reinterpret_cast<boost::uuids::uuid*> (guid)};
+        new (converted) boost::uuids::uuid (strgen (str));
+    }
+    catch (...)
+    {
+        return false;
+    }
     return true;
 }
 
@@ -236,11 +239,10 @@ guid_hash_to_guint (gconstpointer ptr)
 
     guint hash {0};
     unsigned retspot {0};
-    boost::uuids::uuid::const_iterator guidspot {guid->begin ()};
-    while (guidspot != guid->end ()){
+    for (auto guidspot : *guid)
+    {
         hash <<= 4;
-        hash |= *guidspot;
-        ++guidspot;
+        hash |= guidspot;
     }
     return hash;
 }
diff --git a/src/libqof/qof/guid.h b/src/libqof/qof/guid.h
index 6cdbc50..7015e23 100644
--- a/src/libqof/qof/guid.h
+++ b/src/libqof/qof/guid.h
@@ -151,8 +151,8 @@ gchar * guid_to_string_buff (const GncGUID * guid, /*@ out @*/ gchar *buff);
  * 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.
-. */
+ * either return false or replace those values with others.
+ */
 gboolean string_to_guid(const gchar * string, /*@ out @*/ GncGUID * guid);
 
 

commit ce94872ec86c37fb49660004f97d0ce65905c475
Author: lmat <dartme18 at gmail.com>
Date:   Mon Jul 28 16:52:22 2014 -0400

    Cleaned up some code and comments.
    
    There should be no impacting changes in this commit.

diff --git a/src/libqof/qof/guid.cpp b/src/libqof/qof/guid.cpp
index 2f5f2b4..4fda852 100644
--- a/src/libqof/qof/guid.cpp
+++ b/src/libqof/qof/guid.cpp
@@ -108,24 +108,21 @@ guid_copy (const GncGUID *guid)
 {
     const boost::uuids::uuid * old {reinterpret_cast<const boost::uuids::uuid*> (guid)};
     boost::uuids::uuid * ret {new boost::uuids::uuid (*old)};
-    return reinterpret_cast<GncGUID*>(ret);
+    return reinterpret_cast<GncGUID*> (ret);
 }
 
-static GncGUID * nullguid {reinterpret_cast<GncGUID*>(new boost::uuids::uuid{0})};
+static GncGUID * nullguid {reinterpret_cast<GncGUID*> (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)
+guid_null (void)
 {
-    //static boost::uuids::nil_generator nil;
-    //boost::uuids::uuid * ret {new boost::uuids::uuid {0}};
-    //return reinterpret_cast<GncGUID*> (ret);
     return nullguid;
 }
 
 /*Takes an allocated guid pointer and constructs it in place*/
 void
-guid_replace(GncGUID *guid)
+guid_replace (GncGUID *guid)
 {
     static boost::uuids::random_generator gen;
     boost::uuids::uuid * val {reinterpret_cast<boost::uuids::uuid*> (guid)};
@@ -142,7 +139,7 @@ guid_new (void)
 }
 
 GncGUID
-guid_new_return(void)
+guid_new_return (void)
 {
     /*we need to construct our value as a boost guid so that
     it can be deconstructed (in place) in guid_replace*/
@@ -196,16 +193,16 @@ guid_to_string_buff (const GncGUID * guid, gchar *str)
 }
 
 gboolean
-string_to_guid(const char * str, GncGUID * guid)
+string_to_guid (const char * str, GncGUID * guid)
 {
     static boost::uuids::string_generator strgen;
     boost::uuids::uuid * converted {reinterpret_cast<boost::uuids::uuid*> (guid)};
-    new (converted) boost::uuids::uuid (strgen(str));
+    new (converted) boost::uuids::uuid (strgen (str));
     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 false;
@@ -215,7 +212,7 @@ guid_equal(const GncGUID *guid_1, const GncGUID *guid_2)
 }
 
 gint
-guid_compare(const GncGUID *guid_1, const GncGUID *guid_2)
+guid_compare (const GncGUID *guid_1, const GncGUID *guid_2)
 {
     boost::uuids::uuid const * g1 {reinterpret_cast<boost::uuids::uuid const *> (guid_1)};
     boost::uuids::uuid const * g2 {reinterpret_cast<boost::uuids::uuid const *> (guid_2)};
@@ -229,7 +226,7 @@ guid_compare(const GncGUID *guid_1, const GncGUID *guid_2)
 guint
 guid_hash_to_guint (gconstpointer ptr)
 {
-    const boost::uuids::uuid * guid = reinterpret_cast<const boost::uuids::uuid*>(ptr);
+    const boost::uuids::uuid * guid = reinterpret_cast<const boost::uuids::uuid*> (ptr);
 
     if (!guid)
     {
@@ -239,8 +236,8 @@ guid_hash_to_guint (gconstpointer ptr)
 
     guint hash {0};
     unsigned retspot {0};
-    boost::uuids::uuid::const_iterator guidspot {guid->begin()};
-    while (guidspot != guid->end()){
+    boost::uuids::uuid::const_iterator guidspot {guid->begin ()};
+    while (guidspot != guid->end ()){
         hash <<= 4;
         hash |= *guidspot;
         ++guidspot;
@@ -251,8 +248,8 @@ guid_hash_to_guint (gconstpointer ptr)
 gint
 guid_g_hash_table_equal (gconstpointer guid_a, gconstpointer guid_b)
 {
-    return guid_equal (reinterpret_cast<const GncGUID*>(guid_a),
-		       reinterpret_cast<const GncGUID*>(guid_b));
+    return guid_equal (reinterpret_cast<const GncGUID*> (guid_a),
+		       reinterpret_cast<const GncGUID*> (guid_b));
 }
 
 GHashTable *
@@ -275,7 +272,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 78040d2..6cdbc50 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 <peticola at cs.ucdavis.edu>      *
+ *               2014 Aaron Laws <dartmetrash at gmail.com>            *
  *                                                                  *
  * This program is free software; you can redistribute it and/or    *
  * modify it under the terms of the GNU General Public License as   *
@@ -29,45 +30,46 @@ extern "C"
 {
 #endif
 
-typedef struct _gncGuid {
-    unsigned char reserved[16];
-} GncGUID;
-
 #include <stddef.h>
 #include <glib-object.h>
 
 /** @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 <peticola at cs.ucdavis.edu>
+        Copyright 2014 Aaron Laws <dartmetrash at gmail.com>
 */
 
-/** The type used to store guids */
 #define GUID_DATA_SIZE	16
 
 #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
 
@@ -84,13 +86,15 @@ void guid_replace (GncGUID *guid);
  */
 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);
 
 /** 
- * Allocate memory for a GUID. The returned pointer must be freed with
- * guid_free.
+ * 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);
 
@@ -140,11 +144,15 @@ gchar * guid_to_string (const GncGUID * guid);
 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);
 
 

commit cbc292cc91718ce5fb45b7b2e4ce70c74ef1c556
Author: lmat <dartme18 at gmail.com>
Date:   Mon Jul 28 11:15:28 2014 -0400

    Removed the md5 file and updated the build system.
    
    We no longer need md5.h or md5.c because all that work is done in the boost
    uuid implementation.

diff --git a/src/libqof/qof/Makefile.am b/src/libqof/qof/Makefile.am
index 8bc270d..a1e3552 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 edd1fa2..2f5f2b4 100644
--- a/src/libqof/qof/guid.cpp
+++ b/src/libqof/qof/guid.cpp
@@ -50,7 +50,6 @@ extern "C"
 # include <unistd.h>
 #endif
 #include "qof.h"
-#include "md5.h"
 
 }
 #include <boost/uuid/uuid.hpp>
diff --git a/src/libqof/qof/md5.c b/src/libqof/qof/md5.c
deleted file mode 100644
index 8912106..0000000
--- 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 at 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 <drepper at gnu.ai.mit.edu>, 1995.  */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <sys/types.h>
-
-#if STDC_HEADERS || defined _LIBC
-# include <stdlib.h>
-# include <string.h>
-#else
-# ifndef HAVE_MEMCPY
-#include <string.h>
-/* #  define memcpy(d, s, n) bcopy ((s), (d), (n)) */
-# endif
-#endif
-
-#include "md5.h"
-
-#ifdef _LIBC
-# include <endian.h>
-# 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 e501b43..0000000
--- 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 at 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 <stddef.h>
-#include <stdio.h>
-
-#if defined HAVE_LIMITS_H || _LIBC
-# include <limits.h>
-#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 <sys/types.h>
-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 <limits.h>) 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

commit f40a93c6e1b27acaf7fd32bfca4c64ea27a2a860
Author: lmat <dartme18 at gmail.com>
Date:   Fri Jul 25 17:38:33 2014 -0400

    Remove guid_init and guid_shutdown
    
    They no longer do anything, and it's not probable that they ever will.

diff --git a/src/app-utils/test/test-scm-query-string.c b/src/app-utils/test/test-scm-query-string.c
index bb41191..448f0e4 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/doc/design/engine.texi b/src/doc/design/engine.texi
index e5a1ab4..77097d3 100644
--- a/src/doc/design/engine.texi
+++ b/src/doc/design/engine.texi
@@ -378,22 +378,6 @@ 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.
 
- at deftypefun void guid_init (void)
-Initialize the GUID generator with a variety of random sources including
-common system files and /dev/random.
- at end deftypefun
-
- at 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.
- at end deftypefun
-
- at 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.
- at end deftypefun
-
 @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}.
diff --git a/src/libqof/qof/guid.cpp b/src/libqof/qof/guid.cpp
index 15e5245..edd1fa2 100644
--- a/src/libqof/qof/guid.cpp
+++ b/src/libqof/qof/guid.cpp
@@ -124,19 +124,6 @@ guid_null(void)
     return nullguid;
 }
 
-/* Function implementations ****************************************/
-
-void
-guid_init(void)
-{
-    /*Boost takes care of this*/
-}
-
-void
-guid_shutdown (void)
-{
-}
-
 /*Takes an allocated guid pointer and constructs it in place*/
 void
 guid_replace(GncGUID *guid)
diff --git a/src/libqof/qof/guid.h b/src/libqof/qof/guid.h
index 4c56841..78040d2 100644
--- a/src/libqof/qof/guid.h
+++ b/src/libqof/qof/guid.h
@@ -71,22 +71,6 @@ const GncGUID* gnc_value_get_guid (const GValue *value);
  * not including the null terminator. */
 #define GUID_ENCODING_LENGTH 32
 
-
-/** Initialize the id generator with a variety of random
- *  sources.
- *
- *  @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 guid.
  *
  *  @param guid A pointer to an allocated guid data structure.  The
@@ -94,11 +78,9 @@ void guid_shutdown (void);
  */
 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);
 
@@ -121,6 +103,10 @@ 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
diff --git a/src/libqof/qof/qofutil.cpp b/src/libqof/qof/qofutil.cpp
index 2990fce..2881fd7 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 3d61f6d..0bb0a2d 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 82c1d71..bebd5c9 100644
--- a/src/libqof/qof/test/test-gnc-guid.cpp
+++ b/src/libqof/qof/test/test-gnc-guid.cpp
@@ -150,12 +150,10 @@ static void test_gnc_guid_roundtrip (void) {
 
 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 ();
 }
 

commit 30fac05e35b41d316ba9d8f93474879e196c3cbb
Author: lmat <dartme18 at gmail.com>
Date:   Fri Jul 25 17:02:44 2014 -0400

    Corrected uses of guid_to_string.
    
    Previously, guid_to_string had been marked deprecated with a note about
    it not being thread-safe. It was much worse than "not thread safe", it
    was only safe in a particular situation, and its safety was being violated
    throughout the code. It was clear that users of guid_to_string did not
    understand what it was purporting to do because of its varied uses. Most
    uses simply treated it like a Garbage-Collected Java String (use and forget).
    I actually found at least one instance where the string was being freed. (!!!)
    
    I made the method have a particular easy-to-understand semantic: it returns
    a pointer to a string which must be freed by the caller. I then tried to
    track down all uses of this function and correct them. Mostly, I just changed
    the usage to guid_to_string_buff with a stack-allocated string to avoid the
    the malloc/free cycle.

diff --git a/src/app-utils/gnc-component-manager.c b/src/app-utils/gnc-component-manager.c
index 9a47f6d..030eb9c 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 2896717..801f311 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 bfe2701..119c8fa 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 5230737..dab9e3b 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/backend/sql/gnc-transaction-sql.c b/src/backend/sql/gnc-transaction-sql.c
index 46fc3d9..f48ce71 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 f5d6b53..fa4d421 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 b604556..2fd90ca 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 0990e4b..e427a2b 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 64ed084..bb9c7ef 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 14edc79..3d58da2 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 a759eed..c437491 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 dc1de55..e5a1ab4 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.
 
- at deftypefun {const char *} guid_to_string (const GUID * @var{guid})
+ at 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})
diff --git a/src/engine/SchedXaction.c b/src/engine/SchedXaction.c
index c794bac..2f8a47f 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 53fa590..1d539e4 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 5146826..5a0d634 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 9f2c7b9..d65b1bd 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/utest-Split.cpp b/src/engine/test/utest-Split.cpp
index e4165e5..fa149b9 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 53f96ae..719bb67 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_replace (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-sx-editor.c b/src/gnome/dialog-sx-editor.c
index cdc3e87..2013a5e 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 a5c5d61..1344f44 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 268699b..a497cce 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 d191044..9c3df36 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 e5e56ac..544360b 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 429b983..4dfa353 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 f9043e4..9a145d6 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 bbd26d7..198964b 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/guid.cpp b/src/libqof/qof/guid.cpp
index f69890c..15e5245 100644
--- a/src/libqof/qof/guid.cpp
+++ b/src/libqof/qof/guid.cpp
@@ -167,22 +167,22 @@ guid_new_return(void)
     return *ret;
 }
 
-const char *
+gchar *
 guid_to_string (const GncGUID * guid)
 {
     /* We need to malloc here, not 'new' because it will be freed
     by the caller which will use free (not delete).*/
-    char * ret {reinterpret_cast<char*> (malloc (sizeof (char)*GUID_ENCODING_LENGTH+1))};
-    gchar * temp {guid_to_string_buff(guid, ret)};
+    gchar * ret {reinterpret_cast<gchar*> (g_malloc (sizeof (gchar)*GUID_ENCODING_LENGTH+1))};
+    gchar * temp {guid_to_string_buff (guid, ret)};
     if (!temp){
-        delete[] ret;
-        return temp;
+        g_free (ret);
+        return nullptr;
     }
     return ret;
 }
 
 gchar *
-guid_to_string_buff(const GncGUID * guid, char *str)
+guid_to_string_buff (const GncGUID * guid, gchar *str)
 {
     if (!str || !guid) return NULL;
 
diff --git a/src/libqof/qof/guid.h b/src/libqof/qof/guid.h
index fd32446..4c56841 100644
--- a/src/libqof/qof/guid.h
+++ b/src/libqof/qof/guid.h
@@ -127,15 +127,15 @@ GncGUID *guid_copy (const GncGUID *guid);
  *  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.
+ *  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
diff --git a/src/libqof/qof/kvp_frame.cpp b/src/libqof/qof/kvp_frame.cpp
index 299eee5..8d2fd84 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/qofinstance.cpp b/src/libqof/qof/qofinstance.cpp
index 26ec5b8..a814579 100644
--- a/src/libqof/qof/qofinstance.cpp
+++ b/src/libqof/qof/qofinstance.cpp
@@ -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 fd2528c..7d2d0d6 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/test/test-gnc-guid.cpp b/src/libqof/qof/test/test-gnc-guid.cpp
index 447e71e..82c1d71 100644
--- a/src/libqof/qof/test/test-gnc-guid.cpp
+++ b/src/libqof/qof/test/test-gnc-guid.cpp
@@ -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_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};
diff --git a/src/libqof/qof/test/test-kvp_frame.c b/src/libqof/qof/test/test-kvp_frame.c
index ee70a75..d173065 100644
--- a/src/libqof/qof/test/test-kvp_frame.c
+++ b/src/libqof/qof/test/test-kvp_frame.c
@@ -980,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;
@@ -1038,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 );

commit 2a408ab9ef31031440d1877673baad509ab085c3
Author: lmat <dartme18 at gmail.com>
Date:   Fri Jul 25 14:14:09 2014 -0400

    Cleared up GUID construction and allocation
    
    To allocate a GUID, use guid_malloc. To allocate and construct a guid
    (which is actually unique), use guid_new (and be sure to free it using
    guid_free).

diff --git a/src/engine/test/test-guid.c b/src/engine/test/test-guid.c
index 0cacf0b..fdb2408 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_replace(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
diff --git a/src/libqof/qof/guid.cpp b/src/libqof/qof/guid.cpp
index bbda68c..f69890c 100644
--- a/src/libqof/qof/guid.cpp
+++ b/src/libqof/qof/guid.cpp
@@ -89,18 +89,9 @@ gnc_value_get_guid (const GValue *value)
 /* Memory management routines ***************************************/
 
 GncGUID *
-guid_new_ptr_return (void)
-{
-    return reinterpret_cast<GncGUID*> (new boost::uuids::uuid);
-}
-
-/* Deprecated*/
-GncGUID *
 guid_malloc (void)
 {
-    /*We need to actually construct here (not just ::operator new (size_t) -- allocate)
-    because in guid_replace, we assume that the object has already been constructed.
-    Note the boost UUID is a POD, so its constructor is trivial.*/
+    /*Note, the Boost uuid is a POD, so its constructor is trivial*/
     return reinterpret_cast<GncGUID*> (new boost::uuids::uuid);
 }
 
@@ -156,6 +147,14 @@ guid_replace(GncGUID *guid)
     new (val) boost::uuids::uuid (gen ());
 }
 
+GncGUID *
+guid_new (void)
+{
+    GncGUID * ret {guid_malloc ()};
+    guid_replace (ret);
+    return ret;
+}
+
 GncGUID
 guid_new_return(void)
 {
diff --git a/src/libqof/qof/guid.h b/src/libqof/qof/guid.h
index 0644380..fd32446 100644
--- a/src/libqof/qof/guid.h
+++ b/src/libqof/qof/guid.h
@@ -106,16 +106,17 @@ GncGUID guid_new_return (void);
 to never reference any entity. */
 const GncGUID * guid_null (void);
 
-/** Efficiently allocate & free memory for GUIDs
- *  XXX This routine is deprecated. Please use guid_new_return_ptr
- * instead.
-*/
+/** 
+ * Allocate memory for a GUID. The returned pointer must be freed with
+ * guid_free.
+ */
 GncGUID * guid_malloc (void);
 
-/** Allocate and initialize a new guid, and return
-a pointer to it. Caller must call guid_free after to
-release this pointer*/
-GncGUID * guid_new_ptr_return (void);
+/**
+ * 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);
diff --git a/src/libqof/qof/test/test-kvp_frame.c b/src/libqof/qof/test/test-kvp_frame.c
index 688f97a..ee70a75 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_replace (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_replace( 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_replace( 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_replace( 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_replace( 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_replace( 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_replace( guid_orig );
-    guid_copy = guid_malloc();
-    guid_replace( 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;
@@ -1007,8 +999,7 @@ test_kvp_value_to_string( void )
     KvpFrame *frame_orig;
 
     gnc_numeric_orig = gnc_numeric_zero();
-    guid_orig = guid_malloc();
-    guid_replace( guid_orig );
+    guid_orig = guid_new();
     ts_orig.tv_sec = 1;
     ts_orig.tv_nsec = 1;
     list_orig = NULL;
@@ -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_replace( 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 390719c..b6b317f 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_replace( gncGuid );
+    gncGuid = guid_new();
     g_assert( QOF_IS_INSTANCE( fixture->inst ) );
     g_assert( gncGuid );
 

commit 9c82a1e9bc217cc2c12482c3e23b0d442a5f0661
Author: lmat <dartme18 at gmail.com>
Date:   Fri Jul 25 08:26:54 2014 -0400

    Rename guid_new to guid_replace
    
    `new` implies some allocation. Since guid_new was actually constructing
    a guid in place rather than allocating it, it makes much more sense to
    call it guid_replace (or guid_construct). We went with guid_replace.

diff --git a/src/doc/design/engine.texi b/src/doc/design/engine.texi
index a33c31c..dc1de55 100644
--- a/src/doc/design/engine.texi
+++ b/src/doc/design/engine.texi
@@ -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})
@@ -394,7 +394,7 @@ binary data. This provides a way to reliably obtain a given sequence of
 GUIDs.
 @end deftypefun
 
- at deftypefun void guid_new (GUID * @var{guid})
+ at 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/test-core/test-engine-stuff.c b/src/engine/test-core/test-engine-stuff.c
index 77086f0..7e5b57e 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 fe8fb2f..fd84729 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 1835bbf..3f3fdb3 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 20c234a..0cacf0b 100644
--- a/src/engine/test/test-guid.c
+++ b/src/engine/test/test-guid.c
@@ -43,7 +43,7 @@ static void test_null_guid(void)
 
     g = guid_new_return();
     gp = guid_malloc();
-    guid_new(gp);
+    guid_replace(gp);
 
     do_test(guid_equal(guid_null(), guid_null()), "null guids equal");
     do_test(!guid_equal(&g, gp), "two guids equal");
@@ -70,7 +70,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 243307f..2b5b4f8 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 c36ff72..3f030e5 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/experimental/cgi-bin/gnc-server.c b/src/experimental/cgi-bin/gnc-server.c
index 4e19a76..53f96ae 100644
--- a/src/experimental/cgi-bin/gnc-server.c
+++ b/src/experimental/cgi-bin/gnc-server.c
@@ -116,7 +116,7 @@ auth_user (const char * name, const char *passwd)
     if (!name || !passwd) return NULL;
 
     guid = g_new (GncGUID, 1);
-    guid_new (guid);
+    guid_replace (guid);
     logged_in_users = g_list_prepend (logged_in_users, guid);
     session_auth_string = guid_to_string (guid); /* THREAD UNSAFE */
     return session_auth_string;
diff --git a/src/gnome/dialog-print-check.c b/src/gnome/dialog-print-check.c
index 3ee4f0f..b024b4b 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 b9a2cc4..0f707fd 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/libqof/qof/guid.cpp b/src/libqof/qof/guid.cpp
index 72912d8..bbda68c 100644
--- a/src/libqof/qof/guid.cpp
+++ b/src/libqof/qof/guid.cpp
@@ -99,7 +99,7 @@ GncGUID *
 guid_malloc (void)
 {
     /*We need to actually construct here (not just ::operator new (size_t) -- allocate)
-    because in guid_new, we assume that the object has already been constructed.
+    because in guid_replace, we assume that the object has already been constructed.
     Note the boost UUID is a POD, so its constructor is trivial.*/
     return reinterpret_cast<GncGUID*> (new boost::uuids::uuid);
 }
@@ -146,9 +146,9 @@ guid_shutdown (void)
 {
 }
 
-/*Takes an already-constructed guid pointer and re-constructs it in place*/
+/*Takes an allocated guid pointer and constructs it in place*/
 void
-guid_new(GncGUID *guid)
+guid_replace(GncGUID *guid)
 {
     static boost::uuids::random_generator gen;
     boost::uuids::uuid * val {reinterpret_cast<boost::uuids::uuid*> (guid)};
@@ -160,10 +160,10 @@ GncGUID
 guid_new_return(void)
 {
     /*we need to construct our value as a boost guid so that
-    it can be deconstructed (in place) in guid_new*/
+    it can be deconstructed (in place) in guid_replace*/
     boost::uuids::uuid guid;
     GncGUID * ret {reinterpret_cast<GncGUID*> (&guid)};
-    guid_new (ret);
+    guid_replace (ret);
     /*return a copy*/
     return *ret;
 }
diff --git a/src/libqof/qof/guid.h b/src/libqof/qof/guid.h
index 46aa6bd..0644380 100644
--- a/src/libqof/qof/guid.h
+++ b/src/libqof/qof/guid.h
@@ -87,21 +87,12 @@ void guid_init(void);
  *  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.
+/** Generate a new guid.
  *
- *  @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.
diff --git a/src/libqof/qof/qofinstance.cpp b/src/libqof/qof/qofinstance.cpp
index b5ac003..26ec5b8 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;
diff --git a/src/libqof/qof/test/test-gnc-guid.cpp b/src/libqof/qof/test/test-gnc-guid.cpp
index 5369a21..447e71e 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);
@@ -70,7 +70,7 @@ defined in the guid api. We then compare them.*/
 static void test_gnc_guid_to_string (void) {
     GncGUID * guid {guid_malloc()};
     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)};
@@ -135,7 +135,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)};
diff --git a/src/libqof/qof/test/test-kvp_frame.c b/src/libqof/qof/test/test-kvp_frame.c
index ce35637..688f97a 100644
--- a/src/libqof/qof/test/test-kvp_frame.c
+++ b/src/libqof/qof/test/test-kvp_frame.c
@@ -102,7 +102,7 @@ populate_frame (KvpFrame *frame)
     ts.tv_sec = 1;
     ts.tv_nsec = 1;
     guid = guid_malloc ();
-    guid_new (guid);
+    guid_replace (guid);
     g_date_set_dmy (&gdate, 26, 1, 1957);
 
     kvp_frame_set_gint64( frame, "gint64-type", 100 );
@@ -164,7 +164,7 @@ test_kvp_frame_copy( Fixture *fixture, gconstpointer pData )
     test_ts.tv_nsec = 1;
     test_str = "abcdefghijklmnop";
     test_guid = guid_malloc();
-    guid_new( test_guid );
+    guid_replace( test_guid );
     test_frame = kvp_frame_new();
 
     g_assert( fixture->frame );
@@ -224,7 +224,7 @@ test_kvp_frame_set_foo( Fixture *fixture, gconstpointer pData )
     test_ts.tv_sec = 1;
     test_ts.tv_nsec = 1;
     test_guid = guid_malloc();
-    guid_new( test_guid );
+    guid_replace( test_guid );
 
     g_assert( fixture->frame );
     g_assert( kvp_frame_is_empty( fixture->frame ) );
@@ -513,7 +513,7 @@ test_kvp_value_copy( void )
 
     gnc_numeric_orig = gnc_numeric_zero();
     guid_orig = guid_malloc();
-    guid_new( guid_orig );
+    guid_replace( guid_orig );
     ts_orig.tv_sec = 1;
     ts_orig.tv_nsec = 1;
     list_orig = NULL;
@@ -632,7 +632,7 @@ test_kvp_glist_copy( void )
 
     gnc_numeric_orig = gnc_numeric_zero();
     guid_orig = guid_malloc();
-    guid_new( guid_orig );
+    guid_replace( guid_orig );
     ts_orig.tv_sec = 1;
     ts_orig.tv_nsec = 1;
     list_orig = NULL;
@@ -704,7 +704,7 @@ test_kvp_glist_compare( void )
 
     gnc_numeric_orig = gnc_numeric_zero();
     guid_orig = guid_malloc();
-    guid_new( guid_orig );
+    guid_replace( guid_orig );
     ts_orig.tv_sec = 1;
     ts_orig.tv_nsec = 1;
     list_orig = NULL;
@@ -798,9 +798,9 @@ 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_replace( guid_orig );
     guid_copy = guid_malloc();
-    guid_new( guid_copy );
+    guid_replace( guid_copy );
     ts_orig.tv_sec = 1;
     ts_orig.tv_nsec = 1;
     ts_copy.tv_sec = 2;
@@ -1008,7 +1008,7 @@ test_kvp_value_to_string( void )
 
     gnc_numeric_orig = gnc_numeric_zero();
     guid_orig = guid_malloc();
-    guid_new( guid_orig );
+    guid_replace( guid_orig );
     ts_orig.tv_sec = 1;
     ts_orig.tv_nsec = 1;
     list_orig = NULL;
@@ -1094,7 +1094,7 @@ test_kvp_frame_to_string( Fixture *fixture, gconstpointer pData )
 
     test_gnc_numeric = gnc_numeric_zero();
     test_guid = guid_malloc();
-    guid_new( test_guid );
+    guid_replace( test_guid );
     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 a47a8ad..390719c 100644
--- a/src/libqof/qof/test/test-qofinstance.c
+++ b/src/libqof/qof/test/test-qofinstance.c
@@ -98,7 +98,7 @@ test_instance_set_get_guid( Fixture *fixture, gconstpointer pData )
 
     /* set up */
     gncGuid = guid_malloc();
-    guid_new( gncGuid );
+    guid_replace( gncGuid );
     g_assert( QOF_IS_INSTANCE( fixture->inst ) );
     g_assert( gncGuid );
 

commit 26a49f96443cf2039834ea4793482021f68a4885
Author: lmat <dartme18 at gmail.com>
Date:   Wed Jun 11 09:17:09 2014 -0400

    Implement GUID using boost's implementation
    
    Since we're maintaining a C api, the implementation is sometimes less than
    intuitive from either a C or C++ perspective. I am trying to use as much
    boost as possible while making all the guarantees that the C code makes.
    
    One function was declared deprecated because it "wasn't thread safe". This
    was straightforward to repair, and is no longer marked deprecated, and there
    are now two ways to convert GUID to String: passing your own character
    buffer, and having one returned to you that you need to free.

diff --git a/src/libqof/qof/guid.cpp b/src/libqof/qof/guid.cpp
index 235f04b..72912d8 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 <peticola at cs.ucdavis.edu>      *
+ * Copyright (C) 2014 Aaron Laws <dartmetrash at gmail.com>            *
  *                                                                  *
  * 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 <config.h>
@@ -53,30 +52,16 @@ extern "C"
 #include "qof.h"
 #include "md5.h"
 
-#ifdef __cplusplus
 }
-#endif
-
-# ifndef P_tmpdir
-#  define P_tmpdir "/tmp"
-# endif
-
-/* 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
+#include <boost/uuid/uuid.hpp>
+#include <boost/uuid/uuid_generators.hpp>
+#include <boost/uuid/uuid_io.hpp>
+#include <sstream>
+#include <string>
 
+using namespace std;
 
-/* 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 +86,22 @@ gnc_value_get_guid (const GValue *value)
     return val;
 }
 
-
 /* Memory management routines ***************************************/
+
+GncGUID *
+guid_new_ptr_return (void)
+{
+    return reinterpret_cast<GncGUID*> (new boost::uuids::uuid);
+}
+
+/* Deprecated*/
 GncGUID *
 guid_malloc (void)
 {
-    return g_slice_new(GncGUID);
+    /*We need to actually construct here (not just ::operator new (size_t) -- allocate)
+    because in guid_new, we assume that the object has already been constructed.
+    Note the boost UUID is a POD, so its constructor is trivial.*/
+    return reinterpret_cast<GncGUID*> (new boost::uuids::uuid);
 }
 
 void
@@ -114,425 +109,36 @@ guid_free (GncGUID *guid)
 {
     if (!guid)
         return;
-
-    g_slice_free(GncGUID, guid);
+    delete reinterpret_cast<boost::uuids::uuid*> (guid);
 }
 
 
 GncGUID *
 guid_copy (const GncGUID *guid)
 {
-    GncGUID *copy;
-
-    g_return_val_if_fail(guid, NULL);
-    copy = guid_malloc();
-    *copy = *guid;
-    return copy;
+    const boost::uuids::uuid * old {reinterpret_cast<const boost::uuids::uuid*> (guid)};
+    boost::uuids::uuid * ret {new boost::uuids::uuid (*old)};
+    return reinterpret_cast<GncGUID*>(ret);
 }
 
+static GncGUID * nullguid {reinterpret_cast<GncGUID*>(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)
 {
-    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;
+    //static boost::uuids::nil_generator nil;
+    //boost::uuids::uuid * ret {new boost::uuids::uuid {0}};
+    //return reinterpret_cast<GncGUID*> (ret);
+    return nullguid;
 }
 
 /* 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",
-	   (uint64_t) 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;
-}
-
 void
 guid_init(void)
 {
-    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", (uint64_t) bytes);
-
-    if (bytes < THRESHOLD)
-        PWARN("only got %" G_GUINT64_FORMAT " bytes.\n"
-              "The identifiers might not be very random.\n",
-              (uint64_t)bytes);
-
-    guid_initialized = TRUE;
-    LEAVE();
+    /*Boost takes care of this*/
 }
 
 void
@@ -540,208 +146,105 @@ guid_shutdown (void)
 {
 }
 
-#define GUID_PERIOD 5000
-
+/*Takes an already-constructed guid pointer and re-constructs it in place*/
 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--;
+    static boost::uuids::random_generator gen;
+    boost::uuids::uuid * val {reinterpret_cast<boost::uuids::uuid*> (guid)};
+    val->boost::uuids::uuid::~uuid();
+    new (val) boost::uuids::uuid (gen ());
 }
 
 GncGUID
 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_new*/
+    boost::uuids::uuid guid;
+    GncGUID * ret {reinterpret_cast<GncGUID*> (&guid)};
+    guid_new (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)
-{
-    size_t count;
-
-    for (count = 0; count < GUID_DATA_SIZE; count++, buffer += 2)
-        sprintf(buffer, "%02x", data[count]);
-}
-
-/* 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)
-{
-    unsigned char n1, n2;
-    size_t count = -1;
-    unsigned char c1, c2;
-
-    if (NULL == data) return FALSE;
-    if (NULL == string) goto badstring;
-
-    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)
+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<gchar*>(g_static_private_get (&guid_buffer_key));
-    if (string == NULL)
-    {
-        string = static_cast<gchar*>(malloc(GUID_ENCODING_LENGTH + 1));
-        g_static_private_set (&guid_buffer_key, string, g_free);
+    /* We need to malloc here, not 'new' because it will be freed
+    by the caller which will use free (not delete).*/
+    char * ret {reinterpret_cast<char*> (malloc (sizeof (char)*GUID_ENCODING_LENGTH+1))};
+    gchar * temp {guid_to_string_buff(guid, ret)};
+    if (!temp){
+        delete[] ret;
+        return temp;
     }
-#else
-    static GPrivate guid_buffer_key = G_PRIVATE_INIT(g_free);
-    gchar *string;
-
-    string = static_cast<char*>(g_private_get (&guid_buffer_key));
-    if (string == NULL)
-    {
-        string = static_cast<char*>(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;
+    return ret;
 }
 
-char *
-guid_to_string_buff(const GncGUID * guid, char *string)
+gchar *
+guid_to_string_buff(const GncGUID * guid, char *str)
 {
-    if (!string || !guid) return NULL;
-
-    encode_md5_data(guid->data, string);
-
-    string[GUID_ENCODING_LENGTH] = '\0';
-    return &string[GUID_ENCODING_LENGTH];
+    if (!str || !guid) return NULL;
+
+    static boost::uuids::string_generator str_gen;
+    stringstream ostr;
+    boost::uuids::uuid const & tempg = *reinterpret_cast<boost::uuids::uuid const *>(guid);
+    ostr << tempg;
+    string const & val (ostr.str());
+    /*unsigned size {val.size()};
+     size must equal GUID_ENCODING_LENGTH*/
+    unsigned stringspot{0};
+    for (unsigned destspot{0}; destspot < GUID_ENCODING_LENGTH; ++destspot, ++stringspot){
+        switch (stringspot){
+            /*there are hyphens in boost's output, and we need to skip them in our output*/
+            case 8:
+            case 13:
+            case 18:
+            case 23:
+                ++stringspot;
+        }
+        str[destspot] = val[stringspot];
+    }
+    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);
+    static boost::uuids::string_generator strgen;
+    boost::uuids::uuid * converted {reinterpret_cast<boost::uuids::uuid*> (guid)};
+    new (converted) boost::uuids::uuid (strgen(str));
+    return true;
 }
 
 gboolean
 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<boost::uuids::uuid const *> (guid_1)};
+    boost::uuids::uuid const * g2 {reinterpret_cast<boost::uuids::uuid const *> (guid_2)};
+    return *g1 == *g2;
 }
 
 gint
 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<boost::uuids::uuid const *> (guid_1)};
+    boost::uuids::uuid const * g2 {reinterpret_cast<boost::uuids::uuid const *> (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<const GncGUID*>(ptr);
+    const boost::uuids::uuid * guid = reinterpret_cast<const boost::uuids::uuid*>(ptr);
 
     if (!guid)
     {
@@ -749,33 +252,22 @@ guid_hash_to_guint (gconstpointer ptr)
         return 0;
     }
 
-    if (sizeof(guint) <= sizeof(guid->data))
-    {
-        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;
+    guint hash {0};
+    unsigned retspot {0};
+    boost::uuids::uuid::const_iterator guidspot {guid->begin()};
+    while (guidspot != guid->end()){
+        hash <<= 4;
+        hash |= *guidspot;
+        ++guidspot;
     }
+    return hash;
 }
 
 gint
 guid_g_hash_table_equal (gconstpointer guid_a, gconstpointer guid_b)
 {
-    return guid_equal (static_cast<const GncGUID*>(guid_a),
-		       static_cast<const GncGUID*>(guid_b));
+    return guid_equal (reinterpret_cast<const GncGUID*>(guid_a),
+		       reinterpret_cast<const GncGUID*>(guid_b));
 }
 
 GHashTable *
diff --git a/src/libqof/qof/guid.h b/src/libqof/qof/guid.h
index 0dabd42..46aa6bd 100644
--- a/src/libqof/qof/guid.h
+++ b/src/libqof/qof/guid.h
@@ -29,6 +29,10 @@ extern "C"
 {
 #endif
 
+typedef struct _gncGuid {
+    unsigned char reserved[16];
+} GncGUID;
+
 #include <stddef.h>
 #include <glib-object.h>
 
@@ -56,14 +60,6 @@ extern "C"
 
 /** 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)
@@ -105,7 +101,7 @@ void guid_shutdown (void);
  * 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_new (GncGUID *guid);
 
 /** Generate a new id. If no initialization function has been called,
  *  guid_init() will be called before the id is created.
@@ -113,16 +109,24 @@ void guid_new(GncGUID *guid);
  * @return guid A data structure containing a newly allocated GncGUID.
  *  Caller is responsible for calling guid_free().
  */
-GncGUID guid_new_return(void);
+GncGUID guid_new_return (void);
 
 /** Returns a GncGUID which is guaranteed
 to never reference any entity. */
 const GncGUID * guid_null (void);
 
-/** Efficiently allocate & free memory for GUIDs */
+/** Efficiently allocate & free memory for GUIDs
+ *  XXX This routine is deprecated. Please use guid_new_return_ptr
+ * instead.
+*/
 GncGUID * guid_malloc (void);
 
-/* Return a guid set to all zero's */
+/** Allocate and initialize a new guid, and return
+a pointer to it. Caller must call guid_free after to
+release this pointer*/
+GncGUID * guid_new_ptr_return (void);
+
+/*Free the guid pointed to. Do not use this guid any more.*/
 void   guid_free (GncGUID *guid);
 
 GncGUID *guid_copy (const GncGUID *guid);
@@ -133,9 +137,6 @@ GncGUID *guid_copy (const GncGUID *guid);
  *  '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.
- *
  *  @param guid The guid to print.
  *
  *  @return A pointer to the starting character of the string.  The
@@ -155,7 +156,8 @@ 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);
 



Summary of changes:
 configure.ac                                  |  10 +-
 po/POTFILES.in                                |   2 +-
 src/app-utils/gnc-component-manager.c         |   4 +-
 src/app-utils/gnc-state.c                     |   5 +-
 src/app-utils/gnc-sx-instance-model.c         |  10 +-
 src/app-utils/guile-util.c                    |  11 +-
 src/app-utils/test/test-scm-query-string.c    |   1 -
 src/backend/dbi/test/test-backend-dbi-basic.c |   5 +-
 src/backend/sql/gnc-transaction-sql.c         |  18 +-
 src/backend/xml/gnc-bill-term-xml-v2.c        |  44 +-
 src/backend/xml/gnc-schedxaction-xml-v2.c     |  11 +-
 src/backend/xml/gnc-tax-table-xml-v2.c        |  20 +-
 src/backend/xml/sixtp-dom-generators.c        |   8 +-
 src/backend/xml/test/test-xml-transaction.c   |   4 +-
 src/business/business-gnome/dialog-invoice.c  |  13 +-
 src/doc/design/engine.texi                    |  24 +-
 src/engine/SchedXaction.c                     |   4 +-
 src/engine/Split.c                            |   4 +-
 src/engine/Transaction.c                      |   6 +-
 src/engine/gncBillTerm.c                      |   5 +-
 src/engine/test-core/test-engine-stuff.c      |   2 +-
 src/engine/test/test-customer.c               |   2 +-
 src/engine/test/test-employee.c               |   2 +-
 src/engine/test/test-guid.c                   |   7 +-
 src/engine/test/test-job.c                    |   2 +-
 src/engine/test/test-vendor.c                 |   2 +-
 src/engine/test/utest-Split.cpp               |   4 +-
 src/experimental/cgi-bin/gnc-server.c         |  13 +-
 src/gnome/dialog-print-check.c                |   2 +-
 src/gnome/dialog-print-check2.c               |   2 +-
 src/gnome/dialog-sx-editor.c                  |   4 +-
 src/gnome/dialog-sx-editor2.c                 |   3 +-
 src/gnome/gnc-budget-view.c                   |   9 +-
 src/gnome/gnc-plugin-page-account-tree.c      |  10 +-
 src/gnome/gnc-split-reg.c                     |  28 +-
 src/gnome/gnc-split-reg2.c                    |  37 +-
 src/gnome/top-level.c                         |   4 +-
 src/import-export/aqb/gnc-gwen-gui.c          |  25 +-
 src/import-export/log-replay/gnc-log-replay.c |   9 +-
 src/libqof/qof/Makefile.am                    |   9 -
 src/libqof/qof/guid.cpp                       | 730 ++++----------------------
 src/libqof/qof/guid.h                         | 118 ++---
 src/libqof/qof/kvp_frame.cpp                  |   6 +-
 src/libqof/qof/md5.c                          | 445 ----------------
 src/libqof/qof/md5.h                          | 163 ------
 src/libqof/qof/qofinstance.cpp                |   7 +-
 src/libqof/qof/qofquery.cpp                   |   6 +-
 src/libqof/qof/qofutil.cpp                    |   2 -
 src/libqof/qof/qofutil.h                      |   6 +-
 src/libqof/qof/test/test-gnc-guid.cpp         |  57 +-
 src/libqof/qof/test/test-kvp_frame.c          |  36 +-
 src/libqof/qof/test/test-qofinstance.c        |   3 +-
 src/plugins/bi_import/dialog-bi-import.c      |  93 ++--
 53 files changed, 478 insertions(+), 1579 deletions(-)
 delete mode 100644 src/libqof/qof/md5.c
 delete mode 100644 src/libqof/qof/md5.h



More information about the gnucash-changes mailing list