The gnc_numeric is serialised as "num/denom" with no whitespace, and
denom > 0. This function takes advantage of std::from_chars to parse
it. The "num" serialisation is also optimised as a free side effect of
this function.
Covers the final case where having the reconcile window open and
auto-completing a transaction then deleting the transaction before
committing it leaves the transaction in the reconcile window.
We need to signal that the account is modified even if it isn't
because that's what the reconcile window is watching.
Calling xaccSplitDestroy without also calling xaccSplitCommitEdit then
deleting the split list before calling xaccTransCommitEdit prevents
xaccSplitCommitEdit from being called on the supposedly deleted
splits. Not only does this leak them it leaves them in the book
potentially with a dangling parent pointer.
The problem with take 1 was that the duplicate split uses the same lot
and account pointers without adding itself to those lists, causing
checks in unit tests to fail.
This reverts commit 4dbf803041.
The use-after free errors are caused by the compiler reordering the
steps in xaccSplitFree and Transaction's do_destroy. Unfortunately the
corrections here caused trouble in other places, leading to test failures.
- all quote sources are now vector
- get_quote_source_from_type to convert QuoteSourceType to vector<gnc_quote_source>
- the quote sources are modifiable, therefore cannot be const:
see gnc_quote_source_set_fq_installed
"Import CSV" wizard
In MSWin the UnicodeString(char*) ctor assumes that the input string
is encoded in the current codepage, but the input to
gnc_list_formatter is encoded in UTF8. Use the static class function
UnicodeString::fromUTF8 instead.
To use pass -DCMAKE_BUILD_TYPE=Debug or Asan -DCOVERAGE=ON and build as
usual, then do ninja lcov-initialize && ninja check && ninja
lcov-collect. The result will be a directory, <Builddir>/Coverage
containing lcov tracefiles, including an aggregate file gnucash.info
which you can use for further processing. It will also report an overall summary.
Note that only C/C++ files are included.
There's one more target, lcov-generate-html, that you can run after
lcov-collect. It will generate a simple website in
<Builddir>/Coverage-HTML showing coverage by source directory (the
directories in <Builddir> have coverage for generated files). Each
directory path is a clickable link to a page that shows coverage for
each source file; the filenames link to a page for each showing which
lines have been exercised.
strptime will reasonable return false for an incomplete date but it
still fills in the parts of the struct tm that it understands, so bail
out of qof_scan_date_internal when it fails only if all three fields
are present.
Every test was rebuilding it except for gnc-backend-xml.cpp from
scratch, no point in that plus the Address Sanitizer needs the
definition of GncBackendXml.
xaccSplitComputeCapGains creates gains_split pointers in both the Cap Gains Split and its Income split to the original split, but the original's gains_split pointer can point to only one of them, the Cap Gains split. When the original split is freed both the Cap Gains split's and its Income split need their gains_split pointers NULLed or when it's the Income split's turn to be freed it will try to deref the dangling pointer.
The comment on gnc_pricedb_add_price says that writing to the
GNCPrice* after calling it will produce interesting results, and
calling gnc_price_commit_edit and g_object_unref both qualify, so
remove those calls and the corresponding gnc_price_begin_edit.
The intent was always to default to today if the input string isn't
parsable, but two problems prevented that: First,
qof_scan_date_internal didn't check the return value of strptime and
return FALSE if it failed and second gnc_date_edit_get_date_internal
would unnecessarily munge a valid struct tm from gnc_tm_get_today_neutral.
Clear the schema_hash at app shutdown via gnc_prefs_remove_registered
and make that function available to the Python bindings so that
python programs can do so too.
Caused by trying to set the account on the blank split. The blank split
was present because the method used to clear the split list for the
receiving transaction in gnc_float_txn_to_txn_swap_accounts only removed
splits that belong to the transaction, and the blank split doesn't.
Adds new function xaccTransClearSplits to do a more thorough job.
Also improve the documentation for xaccSplitDestroy to better explain when
a transaction will be destroyed if it empties the split list.
# Please enter the commit message for your
changes. Lines starting
- Balancing lots always involves splits in the same account. So
the relevant number to use in the calculations is the split
amount, not the split value.
- Additionally don't assume transactions are single-currency.
So if amounts change, recalculate the associated values
based on deduced exchange rates.
- Finally if the lot balancing resulted in a split to be broken up
into two splits use conservative calculations for the new
splits' values to avoid introducing imbalances due to
rounding errors.
For wrong value type when retrieving a value from the SQL results row.
Profiling showed that most of the SQL load time was spent in handling
these exceptions, and using std::optional instead produced a > 11x
speedup (10 seconds vs. 115 seconds) when loading a large file.
Add new test files that are written with the latest version of GnuCash.
Test loading them, saving to compressed files, loading those compressed
files and writing to an uncompressed file. At every stage check it matches
the canonical version.
The conditions being containing a split from a voided transaction.
Instead of trying to destroy zero-value splits (doomed to fail in
that instance and generally rude otherwise) just remove them from
the lot list.
==88804== 8 bytes in 1 blocks are definitely lost in loss record 12 of 479
==88804== at 0x4848A13: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==88804== by 0x503C550: g_malloc0 (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.7600.1)
==88804== by 0x10B5D8: get_random_string_without (test-stuff.c:312)
==88804== by 0x10B655: get_random_string (test-stuff.c:333)
==88804== by 0x10AA92: test_string_fcn (test-vendor.c:138)
==88804== by 0x10A76B: test_vendor (test-vendor.c:88)
==88804== by 0x10AD5A: main (test-vendor.c:246)
+ 3 more
==88779== 8 bytes in 1 blocks are definitely lost in loss record 9 of 461
==88779== at 0x4848A13: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==88779== by 0x503C550: g_malloc0 (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.7600.1)
==88779== by 0x10B871: get_random_string_without (test-stuff.c:312)
==88779== by 0x10B8EE: get_random_string (test-stuff.c:333)
==88779== by 0x10AB9F: test_string_fcn (test-job.c:157)
==88779== by 0x10A7B1: test_job (test-job.c:87)
==88779== by 0x10AFF3: main (test-job.c:262)
+ 3 more
==88366== 8 bytes in 1 blocks are definitely lost in loss record 11 of 474
==88366== at 0x4848A13: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==88366== by 0x503C550: g_malloc0 (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.7600.1)
==88366== by 0x10B7E9: get_random_string_without (test-stuff.c:312)
==88366== by 0x10B866: get_random_string (test-stuff.c:333)
==88366== by 0x10AB64: test_string_fcn (test-employee.c:140)
==88366== by 0x10A7C1: test_employee (test-employee.c:87)
==88366== by 0x10AF6B: main (test-employee.c:246)
+ 4 more
==88327== 8 bytes in 1 blocks are definitely lost in loss record 13 of 667
==88327== at 0x4848A13: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==88327== by 0x503C550: g_malloc0 (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.7600.1)
==88327== by 0x10B890: get_random_string_without (test-stuff.c:312)
==88327== by 0x10B90D: get_random_string (test-stuff.c:333)
==88327== by 0x10AC7A: test_string_fcn (test-customer.c:146)
==88327== by 0x10A82E: test_customer (test-customer.c:79)
==88327== by 0x10B012: main (test-customer.c:229)
+ 3 more
==88718== 8 bytes in 1 blocks are definitely lost in loss record 21 of 1,880
==88718== at 0x4848A13: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==88718== by 0x503C550: g_malloc0 (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.7600.1)
==88718== by 0x11D6B9: get_random_string_without (test-stuff.c:312)
==88718== by 0x11D736: get_random_string (test-stuff.c:333)
==88718== by 0x116A91: test_commodity() (test-commodities.cpp:60)
==88718== by 0x117355: main (test-commodities.cpp:196)
+ 5 more
==88262== 6 bytes in 1 blocks are definitely lost in loss record 5 of 2,117
==88262== at 0x4848A13: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==88262== by 0x503C550: g_malloc0 (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.7600.1)
==88262== by 0x10B043: get_random_string_without (test-stuff.c:312)
==88262== by 0x10B0C0: get_random_string (test-stuff.c:333)
==88262== by 0x10A6E0: test_string_fcn (test-address.c:79)
==88262== by 0x10A694: test_address (test-address.c:69)
==88262== by 0x10A7C5: main (test-address.c:94)
+ 7 more
Valgrind uses "still reachable" because of the call to exit()
==87185== 94 bytes in 1 blocks are still reachable in loss record 193 of 241
==87185== at 0x4843828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==87185== by 0x15C234: main (test-xml2-is-file.cpp:42)
==87185==
==66427== 128 bytes in 1 blocks are definitely lost in loss record 22 of 25
==66427== at 0x4843738: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==66427== by 0x49B85EF: g_realloc (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.7600.1)
==66427== by 0x49D6EF1: ??? (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.7600.1)
==66427== by 0x49D6F6F: g_string_sized_new (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.7600.1)
==66427== by 0x499AB00: ??? (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.7600.1)
==66427== by 0x499B2D8: g_build_filename (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.7600.1)
==66427== by 0x10A498: main (test-userdata-dir-invalid-home.c:74)
==66427==
==68902== 8 bytes in 1 blocks are definitely lost in loss record 7 of 251
==68902== at 0x4843828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==68902== by 0x5225948: g_malloc (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.7600.1)
==68902== by 0x5240ED2: g_strdup (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.7600.1)
==68902== by 0x13135E: g_strdup_inline (gstrfuncs.h:321)
==68902== by 0x13135E: dom_tree_to_text(_xmlNode*) (sixtp-dom-parsers.cpp:500)
==68902== by 0x141758: test_bad_string() (test-string-converters.cpp:70)
==68902== by 0x1417D8: main (test-string-converters.cpp:82)
==68902==
==68902== 93 bytes in 5 blocks are definitely lost in loss record 199 of 251
==68902== at 0x4843828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==68902== by 0x5225948: g_malloc (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.7600.1)
==68902== by 0x5240ED2: g_strdup (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.7600.1)
==68902== by 0x13135E: g_strdup_inline (gstrfuncs.h:321)
==68902== by 0x13135E: dom_tree_to_text(_xmlNode*) (sixtp-dom-parsers.cpp:500)
==68902== by 0x14169B: test_string_converters() (test-string-converters.cpp:55)
==68902== by 0x1417D3: main (test-string-converters.cpp:81)
==68902==
==68902== 260 (120 direct, 140 indirect) bytes in 1 blocks are definitely lost in loss record 242 of 251
==68902== at 0x4843828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==68902== by 0x48D5B84: xmlNewNode (in /usr/lib/x86_64-linux-gnu/libxml2.so.2.9.14)
==68902== by 0x133873: text_to_dom_tree(char const*, char const*) (sixtp-dom-generators.cpp:53)
==68902== by 0x141748: test_bad_string() (test-string-converters.cpp:68)
==68902== by 0x1417D8: main (test-string-converters.cpp:82)
==68902==
==68902== 1,353 (600 direct, 753 indirect) bytes in 5 blocks are definitely lost in loss record 248 of 251
==68902== at 0x4843828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==68902== by 0x48D5B84: xmlNewNode (in /usr/lib/x86_64-linux-gnu/libxml2.so.2.9.14)
==68902== by 0x133873: text_to_dom_tree(char const*, char const*) (sixtp-dom-generators.cpp:53)
==68902== by 0x14168B: test_string_converters() (test-string-converters.cpp:54)
==68902== by 0x1417D3: main (test-string-converters.cpp:81)
==68902==
==91379== 19 bytes in 1 blocks are definitely lost in loss record 2 of 9
==91379== at 0x4843828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==91379== by 0x48D1948: g_malloc (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.7600.1)
==91379== by 0x48ED5B0: g_strconcat (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.7600.1)
==91379== by 0x48B845F: ??? (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.7600.1)
==91379== by 0x48B869E: g_dir_make_tmp (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.7600.1)
==91379== by 0x10935E: main (test-resolve-file-path.c:71)
==87254== 40 (24 direct, 16 indirect) bytes in 1 blocks are definitely lost in loss record 107 of 242
==87254== at 0x4843828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==87254== by 0x503B948: g_malloc (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.7600.1)
==87254== by 0x502F909: g_list_prepend (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.7600.1)
==87254== by 0x194E83: QofQueryCoreTest_construct_predicate_guid_Test::TestBody() (gtest-qofquerycore.cpp:94)
==67054== 320 bytes in 32 blocks are definitely lost in loss record 2,213 of 2,238
==67054== at 0x4848A13: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==67054== by 0x503C550: g_malloc0 (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.7600.1)
==67054== by 0x118AD8: get_random_transaction_with_currency (test-engine-stuff.cpp:1395)
==67054== by 0x119897: add_random_transactions_to_book (test-engine-stuff.cpp:1848)
==67054== by 0x115FE8: run_test() (test-lots.cpp:99)
==67054== by 0x1160BF: main (test-lots.cpp:135)
==67054==
g_assert() can be compiled out, so should not be used for tests
g_assert_true was removed
to fis https://bugs.gnucash.org/show_bug.cgi?id=792008 because
g_assert_true was introduced in glib-2.38 and at the time GnuCash required
only glib-2.26. GnuCash has required glib >= 2.40 since 8acbc41c6 so
g_assert_true can be restored.
Alas, poor yahoo_json. After months of valiant struggle to keep up
with Yahoo!'s moving their API around the Finance::Quote team has
abandoned it, replacing it with a screen saver. Those tend to be
unstable so use alphavantage for testing.
Using a "close" time of 16:00 is a nice idea except that we don't know
what timezone it is, so it's not terribly useful. Use neutral time
instead so that the date will be right in all timezones.