And in Windows only with the value from the environment if there is one.
Calling it with "" in Windows ignores the environment and sets it to the
system settings.
Ensure that all includes of swig-runtime.h are *followed* by
including guile-mappings.h so that the defines masking
scm_to_utf8_string and scm_from_utf8_string are undone.
When you have multiple loggers enabled, the log file indentations are
partly based on logger name length and so you can have false
indentations which can cause confusion. This change gets the maximum
name logger length and uses this for all with a minimum default length
of 12 characters.
Caused by the introduction of caching used in gnc_pricedb_nth_price,
when prices were deleted, the cached list was never updated and so the
tree model could reference a deleted price and hence crash. This also
affected adding prices as the new prices would not show due to the
cache not being updated. To fix this a function was added to reset the
cache when prices are updated from the model.
This reverts commit aa53c23239, reversing
changes made to 3c946a8449, because
aa53c23 was based on master and so undid other changes made to maint
since the last merge-to-master.
copied function created by Mark Weaver, core guile dev and augmented
to selectively replace substring indices
This is a much more efficient function than the previous
gnc:substring-replace which will constantly split lists using
substring, and create new strings using string-append.
It also does tail call optimization properly, unlike the previous
functions.
https://lists.gnu.org/archive/html/guile-devel/2013-09/msg00029.html -
original
"Here's an implementation that does this benchmark about 80 times
faster on my machine: (20 milliseconds vs 1.69 seconds)
--8<---------------cut here---------------start------------->8---
(define* (string-replace-substring s substr replacement
#:optional
(start 0)
(end (string-length s)))
(let ((substr-length (string-length substr)))
(if (zero? substr-length)
(error "string-replace-substring: empty substr")
(let loop ((start start)
(pieces (list (substring s 0 start))))
(let ((idx (string-contains s substr start end)))
(if idx
(loop (+ idx substr-length)
(cons* replacement
(substring s start idx)
pieces))
(string-concatenate-reverse (cons (substring s start)
pieces))))))))
--8<---------------cut here---------------end--------------->8---
The reason this is so much faster is because it avoids needless
generation of intermediate strings."
Add tests for libgnucash/scm/utilities.scm functions
- tests for list<->vec
- tests for gnc:substring-replace
- tests for gnc:substring-replace-from-to
The latter confirms that the comment before the function definition
is *incorrect* - it describes that substring-replace-from-to will
start from the 2nd substring for the first substitution, and
performs 2 substitutions. However the comment illustrates only 1
substitution. The test suite performs the test according to code
behaviour, rather than the comment. This issue is moot in practice
because the end-after is always called with negative in the code
base.
original comment:
;; gnc:substring-replace-from-to
;; same as gnc:substring-replace extended by:
;; start: from which occurrence onwards the replacement shall start
;; end-after: max. number times the replacement should executed
;;
;; Example: (gnc:substring-replace-from-to "foobarfoobarfoobar" "bar" "xyz" 2 2)
;; returns "foobarfooxyzfoobar".
When testing for a MS Windows path which has a ":", a gvfs path with the
format '/run/user/1000/gvfs/smb-share:server=192.168.1.11,share=public/
test-xml-file.gnucash' is recognised as a Windows path. To avoid this
expand the test to ":/" and also ":\"
On Windows boost::filesystem::path's string() produces a string
that goes out of scope with the function in which it's called, so
returning its c_str() ptr yields freed memory, usually full of garbage.
This has an interesting side effect in gnc-file.c's check_file_path():
Since the memory is freed, g_path_get_dirname() reuses it after an
iteration or two, writing its result into the same address. The
following strcmp naturally returns 0 because it's comparing two
instances of the same ptr, so check_file_path falsely reports that
the proposed save path is in GNC_USERDATA_DIR.
Windows file uri's can be of the form 'file:///N:/bob.txt' so change
the gnc_uri_get_components to remove a left over '/' at the start so
gnc_resolve_file_path gets the absolute path correctly. Also change
gnc_uri_create_uri to add an extra '/' for Windows file uri's.
Add function to create an absolute file path from a prefix path and a
relative one. If the prefix is null, then the root directory of the
current path is used.
If the original date is an end-of-month date, we take it as an
indicator they always want monthdelta dates to be end-of-months.
This works for monthly/quarterly/halfyearly/annual.
Addendum to commit 65bfeaf5de which was
deemed to be an incomplete fix.
Also I'd forgotten to activate a test in test-date-utilities. Enable it.
this will modify a test which was calibrated to record purchase price
only. fix transaction creation to add prices for both purchase and
sales, and also fix test which was assuming no sale price was bring
recorded.
This is the general case for any transaction creation. Rewrite other
transaction creation routines to use it. All tests still work
unchanged, which confirms this function works well.
This will allow tests to create multisplit transactions, of an
arbitrary number of splits. If the list-of-split's values are not
balanced (i.e. total 0), the engine will create an Imbalance-CUR
split.
The motivation is to allow creation of complex multisplit
multicommodity transactions eg USD50 + GBP20 (USD25) = EUR66 (USD75)
as well as their prices GBP/USD = 25/20 and EUR/USD = 75/66.
* USD -50
* USD -25 = GBP -20
* USD +75 = EUR +66
This will be useful in creating tests for stock-based reports, whereby
stock sales need splits in STOCK/ASSET/INCOME accounts.
the option lookup mechanism will dynamically translate option
names. warn the user if this takes place so that the report writer may
use new option names.
Use the Scheme rationalize method to convert the decimal numbers
from Finance::Quote to ratinal numbers. This avoids rediculous
precision like 8515625000000001/3906250000000000 for 2.18.
If a saved-report with e.g. relative date, multichoice option is
unknown, the report would crash, and the Report-Options would
segfault. This commit fixes both: report-date defaults to 'today',
multichoice-options defaults to default-value.
Following this commit, if a report loads a saved-report or .gcm from a
future version, a gnc:warn will be emitted and the report will not
crash; it will use relative-date today. Multichoice will remain the
default value. Report Options will not segfault.
The user will be notified via a gnc:gui-warn dialog
gnc:gui-[warn|error|msg] are new global functions.
By default they mirror gnc:warn/error/msg. However then gnome is
available, they will display appropriate warn/error/info dialog in
addition to outputting to console.
Instead of recursing the date, we calculate the next month using an
index-based multiplier, and apply modulo/remainder as appropriate to
determine the next month/year.
Then we attempt to create new mktime, and if the resulting mktime's
month is not as expected, reduce the mday by 1 until resulting month
is correct. This fixes monthly intervals for end-of-month days.
Test via monthly/quarterly deltas, and also includes leapyear
calculation.
Revert using boost::locale to generate std::locales as boost::locale-
generated locales don't implement std::locale::facet and there was
a bug in the boost::locale ICU wrapper code that caused the wrong year
to be output for the last 3 days of December.
GCC's libstdc++ supports only the "C" locale on Windows and throws if
one attempts to create any other kind. For dates we work around this
by using wstrftime() to format according to locale and then convert
the UTF16 string to UTF8. wstrftime() interprets the time zone flags
%z, %Z, and %ZP differently so we process those first before calling
strftime. This will have the unfortunate effect of not localizing
timezone names but it's as close as we can get.
Use built-in glib functions to retrieve the list of per-currency price
lists, concatenate them into a single list, instead of doing it all in
hand-rolled loops.
Sorting is preformed by the calling GncTreeViewPrice so this removes
sorting from gnc_pricedb_nth_price.
There's no concurrency concern because gnc_pricedb_nth_price is a
GUI callback and so must run in the GUI thread.
It seems that std::locales created by boost::locale::generator are
not entirely compatible: If used to create a new locale with a facet
for boost::date_time one ends up with the C locale and the facet.
For the time being avoid the problem by using boost::locale to format
dates and times. std::chrono gets calendar functions in C++20 so we
can switch date-time backends once we can adopt it.
We can't use std::locale::global because all streams imbue it by
default and if it's not 'C' (aka std::locale::classic) then we
must imbue all the streams that we don't want localized, and that's
most of them.
Provides error checking for setting the C++ locale from the environment.
This is necessary both because the environment might have an invalid
locale, which would cause an unhandled exception crash.
On windows std::locale("") can't handle some Microsoft-style locale
strings (e.g. Spanish_Spain) so we use boost::locale's gen("") function
to set the locale--though even that can't handle a Microsoft-style
locale string with an appended charset (e.g. Spanish_Spain.1252) and
that's what glibc's setlocale(LC_ALL, NULL) emits.
Testing notes: Based on the averages of 3 runs, the net
user CPU to save the XML file I use is:
10.2 seconds without this change
7.6 seconds with this change
In my environment the first call to the format routine
in question, the call that sets the cache value, is at
the end of the XML load.
The refactoring provides roughly 10% reduction in user CPU
use for XML file load by moving an expensive function
to within an if-clause where the result is used. The diff looks
like a full re-write but only the if statements, indenting,
and commentary changed.
This value is queried on each comparison of split or txn sort function,
which means it is called quite a lot. Avoiding the KVP lookup of this
property gains a lot in terms of CPU cycles.
Because of https://sourceforge.net/p/libdbi-drivers/bugs/24.
This issue causes trouble in save_may_clobber_data() as well, so
work around it by using a SQL query instead of dbi_conn_get_table_list.
Until now GNC_CONFIG_HOME was more or less hard-coded.
Now it can be set via environment variable GNC_CONFIG_HOME.
In addition it will automatically be created to avoid potential
user confusion.
when moving entry between accounts
When using the cut transaction option the 'associated file' value was
not being pasted to the new transaction. Added scheme code to get this
value and save it to new transaction when using 'cut/copy' and then
'paste' operations. When using the duplicate option, a dialogue allows
you to keep the copied association or not. It does not get copied for
autocomplete.
This involves renaming 3 functions:
gnc_uri_get_protocol -> gnc_uri_get_scheme
gnc_uri_is_known_protocol -> gnc_uri_is_known_scheme
gnc_uri_is_file_protocol -> gnc_uri_is_file_scheme
The *_protocol variants are marked as deprecated.
Additionally a number of local variables have been renamed from
protocol to scheme to support this change.
- gnc_uri_get_components will now return NULL as protocol if the input is a normal
file system path instead of a uri (it used to return 'file')
- gnc_uri_get_protocol will now return NULL if the input is a normal
file system path instead of a uri (it used to return 'file')
- gnc_uri_is_file_protocol now returns FALSE if protocol is NULL (it used to return TRUE)
- gnc_uri_is_file_uri now returns FALSE if input is a normal file
system path instead of a uri (it used to return TRUE)
- a new function gnc_uri_targets_local_fs will return TRUE only if its input
is either a file uri or a normal file system path. This function is now mostly
used instead of gnc_uri_is_file_uri in the current code base
- a new function gnc_uri_is_uri is added to check whether its input
is a valid uri (has protocol, path and hostname for non-file uris)
Previously the account color slot has been populated with "Not Set"
when any field for the account has been edited and saved. This routine
should run once and remove all such entries.
There are a very few left that need deeper study, but this gets
rid of most of the noise. For the most part it's just getting rid of
extra variables or removing an assignment that is always
replaced later but before any reads of the variable. A few are
discarded result variables.
It can't, because if b is 0 the function would have
returned already; since b.m_hi is 0 b.m_lo can't be. The assert
reassures clang that this is the case.
We need to compare the magnitudes of the remainder and the denominator
in order to round negative numbers correctly. Note that while gnc_numeric
is constrained to a positive denominator the C++ rounding functions cannot
assume that constraint in all cases.
Combined with the previous commit, this fixes
Bug 796949 - Incorrect conversion of 0,01 USD to EUR
So that the returned price tuple has the two commodities of interest
converted to a common currency. Before the first pair that that shared
any random currency would be returned, perhaps creating an absurd result.
This function complements gnc_time64_get_day_begin/end. There was
time64CanonicalDayTime but this returned noon of the given day, where we
want 10:59am in most cases. I haven't changed time64CanonicalDayTime
directly as that may break assumptions in other parts of the code.
Instead I have created a new function that can be gradually introduced.
Use a variant of xaccParseAmount that allows to ignore the locale's positive_sign character
or the + sign if locale doesn't define a positive_sign character.
In a future redesign it would probably be better to replace use
of xaccParseAmount with some variant of the gnc-expression-parser
but that would require more that a few tweaks to get right.
date-posted to not be saved.
Check the stored GDate for being in the GncDateTime range as well
as the GDate range before returning it and check trans->date-posted
against INT64_MAX instead of 0 before changing it.
The first fix for this bug handled structs tm with ambiguous times.
This one fixes the GncDate constructor when the time is ambiguous
because it's in the DST-change hour, using the same add 3 hours,
construct the LDT, and subtract the 3 hours from the result.
The string constructor handles only simple-offset HH:MM timezones and so
is immune to the bug.
When the preference dialogue is loaded and options are set, the ones
with registered callbacks fire causing parts of Gnucash to be updated.
This was observed with gnc_split_register_load being executed 5 times
for each open register when the preference dialogue was loaded.
To overcome this, a couple of functions have been created to block and
unblock all registered prefs and used while the preference dialogue is
loaded.
And don't ask to save a not-dirty or empty book, fixing
Bug 794870 - If no book is opened, gnucash still asks if the user wants
to save changes when opening a file
These are queried continuously by the owner tree view (on Customer/Vendor/Employee
Overview pages) and recalculating them is an expensive operation.
The cache will be invalidated each time a lot reated to the owner
changes (modify or delete). The net effect is a huge responsiveness
improvement of said overviews in case of a large book.
Any operation that can overflow will throw an underflow if it's a
negative number. The C interface needs to catch both to prevent
unhandled exception crashes,