gnucash maint: Multiple changes pushed

Geert Janssens gjanssens at code.gnucash.org
Fri Aug 17 10:26:32 EDT 2018


Updated	 via  https://github.com/Gnucash/gnucash/commit/54a5097c (commit)
	 via  https://github.com/Gnucash/gnucash/commit/34cb4925 (commit)
	from  https://github.com/Gnucash/gnucash/commit/44644694 (commit)



commit 54a5097c60496d005f497b2315f063734d8bcd9f
Author: Geert Janssens <geert at kobaltwit.be>
Date:   Sat Aug 11 18:35:33 2018 +0200

    Bug 796777 - CVE-2008-1391: Integer overflow in included strfmon function
    
    We only used strfmon in one source file to generate three fixed format
    strings. Instead of updating to a newer strfmon in borrowed I have
    chosen to reimplement the string formatters for these strings in C++.
    Note this is *not* a full c++ conversion of the full functionality
    of assistant-loan. Only the string parsing has been redone.

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 42a23b6..b2fcffb 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -732,7 +732,6 @@ set (HAVE_PTHREAD_PRIO_INHERIT 1)
 set (HAVE_SCANF_LLD 1)
 set (HAVE_SETENV 1)
 set (HAVE_STPCPY 1)
-set (HAVE_STRFMON 1)
 set (HAVE_STRPTIME 1)
 set (HAVE_STRUCT_TM_GMTOFF 1)
 set (HAVE_TIMEGM 1)
diff --git a/borrowed/libc/CMakeLists.txt b/borrowed/libc/CMakeLists.txt
index c88f8d1..f89cfe1 100644
--- a/borrowed/libc/CMakeLists.txt
+++ b/borrowed/libc/CMakeLists.txt
@@ -1,4 +1,4 @@
-set(libc_SOURCES libc-missing-noop.c setenv.c strfmon.c strptime.c)
-set(libc_HEADERS pow.h setenv.h strfmon.h strptime.h)
+set(libc_SOURCES libc-missing-noop.c setenv.c strptime.c)
+set(libc_HEADERS pow.h setenv.h strptime.h)
 
-set_dist_list(libc_DIST CMakeLists.txt ${libc_SOURCES} ${libc_HEADERS})
\ No newline at end of file
+set_dist_list(libc_DIST CMakeLists.txt ${libc_SOURCES} ${libc_HEADERS})
diff --git a/borrowed/libc/strfmon.c b/borrowed/libc/strfmon.c
deleted file mode 100644
index d5ce44f..0000000
--- a/borrowed/libc/strfmon.c
+++ /dev/null
@@ -1,619 +0,0 @@
-/*-
- * Copyright (c) 2001 Alexey Zelkin <phantom at FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- */
-
-
-#include <sys/types.h>
-#include <ctype.h>
-#include <errno.h>
-#include <limits.h>
-#include <locale.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "strfmon.h"
-
-/* internal flags */
-#define NEED_GROUPING           0x01    /* print digits grouped (default) */
-#define SIGN_POSN_USED          0x02    /* '+' or '(' usage flag */
-#define LOCALE_POSN             0x04    /* use locale defined +/- (default) */
-#define PARENTH_POSN            0x08    /* enclose negative amount in () */
-#define SUPRESS_CURR_SYMBOL     0x10    /* suppress the currency from output */
-#define LEFT_JUSTIFY            0x20    /* left justify */
-#define USE_INTL_CURRENCY       0x40    /* use international currency symbol */
-#define IS_NEGATIVE             0x80    /* is argument value negative ? */
-
-/* internal macros */
-#define PRINT(CH) do {                                          \
-        if (dst >= s + maxsize)                                 \
-                goto e2big_error;                               \
-        *dst++ = CH;                                            \
-} while (0)
-
-#define PRINTS(STR) do {                                        \
-        char *tmps = STR;                                       \
-        while (*tmps != '\0')                                   \
-                PRINT(*tmps++);                                 \
-} while (0)
-
-#define GET_NUMBER(VAR) do {                                    \
-        VAR = 0;                                                \
-        while (isdigit((unsigned char)*fmt)) {                  \
-                VAR *= 10;                                      \
-                VAR += *fmt - '0';                              \
-                fmt++;                                          \
-        }                                                       \
-} while (0)
-
-#define GRPCPY(howmany) do {                                    \
-        int i = howmany;                                        \
-        while (i-- > 0) {                                       \
-                avalue_size--;                                  \
-                *--bufend = *(avalue+avalue_size+padded);       \
-        }                                                       \
-} while (0)
-
-#define GRPSEP do {                                             \
-        *--bufend = thousands_sep;                              \
-        groups++;                                               \
-} while (0)
-
-static void __setup_vars(int, char *, char *, char *, char **);
-static int __calc_left_pad(int, char *);
-static char *__format_grouped_double(double, int *, int, int, int);
-
-ssize_t
-strfmon(char * __restrict s, size_t maxsize, const char * __restrict format,
-    ...)
-{
-        va_list         ap;
-        char            *dst;           /* output destination pointer */
-        const char      *fmt;           /* current format position pointer */
-        struct lconv    *lc;            /* pointer to lconv structure */
-        char            *asciivalue;    /* formatted double pointer */
-
-        int             flags;          /* formatting options */
-        int             pad_char;       /* padding character */
-        int             pad_size;       /* pad size */
-        int             width;          /* field width */
-        int             left_prec;      /* left precision */
-        int             right_prec;     /* right precision */
-        double          value;          /* just value */
-        char            space_char = ' '; /* space after currency */
-
-        char            cs_precedes,    /* values gathered from struct lconv */
-                        sep_by_space,
-                        sign_posn,
-                        *signstr,
-                        *currency_symbol;
-
-        char            *tmpptr;        /* temporary vars */
-        int             sverrno;
-
-        va_start(ap, format);
-
-        lc = localeconv();
-        dst = s;
-        fmt = format;
-        asciivalue = NULL;
-        currency_symbol = NULL;
-        pad_size = 0;
-
-        while (*fmt) {
-                /* pass nonformating characters AS IS */
-                if (*fmt != '%')
-                        goto literal;
-
-                /* '%' found ! */
-
-                /* "%%" mean just '%' */
-                if (*(fmt+1) == '%') {
-                        fmt++;
-        literal:
-                        PRINT(*fmt++);
-                        continue;
-                }
-
-                /* set up initial values */
-                flags = (NEED_GROUPING|LOCALE_POSN);
-                pad_char = ' ';         /* padding character is "space" */
-                left_prec = -1;         /* no left precision specified */
-                right_prec = -1;        /* no right precision specified */
-                width = -1;             /* no width specified */
-                value = 0;              /* we have no value to print now */
-
-                /* Flags */
-                while (1) {
-                        switch (*++fmt) {
-                                case '=':       /* fill character */
-                                        pad_char = *++fmt;
-                                        if (pad_char == '\0')
-                                                goto format_error;
-                                        continue;
-                                case '^':       /* not group currency  */
-                                        flags &= ~(NEED_GROUPING);
-                                        continue;
-                                case '+':       /* use locale defined signs */
-                                        if (flags & SIGN_POSN_USED)
-                                                goto format_error;
-                                        flags |= (SIGN_POSN_USED|LOCALE_POSN);
-                                        continue;
-                                case '(':       /* enclose negatives with () */
-                                        if (flags & SIGN_POSN_USED)
-                                                goto format_error;
-                                        flags |= (SIGN_POSN_USED|PARENTH_POSN);
-                                        continue;
-                                case '!':       /* suppress currency symbol */
-                                        flags |= SUPRESS_CURR_SYMBOL;
-                                        continue;
-                                case '-':       /* alignment (left)  */
-                                        flags |= LEFT_JUSTIFY;
-                                        continue;
-                                default:
-                                        break;
-                        }
-                        break;
-                }
-
-                /* field Width */
-                if (isdigit((unsigned char)*fmt)) {
-                        GET_NUMBER(width);
-                        /* Do we have enough space to put number with
-                         * required width ?
-                         */
-                        if (dst + width >= s + maxsize)
-                                goto e2big_error;
-                }
-
-                /* Left precision */
-                if (*fmt == '#') {
-                        if (!isdigit((unsigned char)*++fmt))
-                                goto format_error;
-                        GET_NUMBER(left_prec);
-                }
-
-                /* Right precision */
-                if (*fmt == '.') {
-                        if (!isdigit((unsigned char)*++fmt))
-                                goto format_error;
-                        GET_NUMBER(right_prec);
-                }
-
-                /* Conversion Characters */
-                switch (*fmt++) {
-                        case 'i':       /* use international currency format */
-                                flags |= USE_INTL_CURRENCY;
-                                break;
-                        case 'n':       /* use national currency format */
-                                flags &= ~(USE_INTL_CURRENCY);
-                                break;
-                        default:        /* required character is missing or
-                                           premature EOS */
-                                goto format_error;
-                }
-
-                if (flags & USE_INTL_CURRENCY) {
-                        currency_symbol = strdup(lc->int_curr_symbol);
-                        if (currency_symbol != NULL)
-                                space_char = *(currency_symbol+3);
-                } else
-                        currency_symbol = strdup(lc->currency_symbol);
-
-                if (currency_symbol == NULL)
-                        goto end_error;                 /* ENOMEM. */
-
-                /* value itself */
-                value = va_arg(ap, double);
-
-                /* detect sign */
-                if (value < 0) {
-                        flags |= IS_NEGATIVE;
-                        value = -value;
-                }
-
-                /* fill left_prec with amount of padding chars */
-                if (left_prec >= 0) {
-                        pad_size = __calc_left_pad((flags ^ IS_NEGATIVE),
-                                                        currency_symbol) -
-                                   __calc_left_pad(flags, currency_symbol);
-                        if (pad_size < 0)
-                                pad_size = 0;
-                }
-
-                asciivalue = __format_grouped_double(value, &flags,
-                                left_prec, right_prec, pad_char);
-                if (asciivalue == NULL)
-                        goto end_error;         /* errno already set     */
-                                                /* to ENOMEM by malloc() */
-
-                /* set some variables for later use */
-                __setup_vars(flags, &cs_precedes, &sep_by_space,
-                                &sign_posn, &signstr);
-
-                /*
-                 * Description of some LC_MONETARY's values:
-                 *
-                 * p_cs_precedes & n_cs_precedes
-                 *
-                 * = 1 - $currency_symbol precedes the value
-                 *       for a monetary quantity with a non-negative value
-                 * = 0 - symbol succeeds the value
-                 *
-                 * p_sep_by_space & n_sep_by_space
-                 *
-                 * = 0 - no space separates $currency_symbol
-                 *       from the value for a monetary quantity with a
-                 *       non-negative value
-                 * = 1 - space separates the symbol from the value
-                 * = 2 - space separates the symbol and the sign string,
-                 *       if adjacent.
-                 *
-                 * p_sign_posn & n_sign_posn
-                 *
-                 * = 0 - parentheses enclose the quantity and the
-                 *       $currency_symbol
-                 * = 1 - the sign string precedes the quantity and the
-                 *       $currency_symbol
-                 * = 2 - the sign string succeeds the quantity and the
-                 *       $currency_symbol
-                 * = 3 - the sign string precedes the $currency_symbol
-                 * = 4 - the sign string succeeds the $currency_symbol
-                 *
-                 */
-
-                tmpptr = dst;
-
-                while (pad_size-- > 0)
-                        PRINT(' ');
-
-                if (sign_posn == 0 && (flags & IS_NEGATIVE))
-                        PRINT('(');
-
-                if (cs_precedes == 1) {
-                        if (sign_posn == 1 || sign_posn == 3) {
-                                PRINTS(signstr);
-                                if (sep_by_space == 2)          /* XXX: ? */
-                                        PRINT(' ');
-                        }
-
-                        if (!(flags & SUPRESS_CURR_SYMBOL)) {
-                                PRINTS(currency_symbol);
-
-                                if (sign_posn == 4) {
-                                        if (sep_by_space == 2)
-                                                PRINT(space_char);
-                                        PRINTS(signstr);
-                                        if (sep_by_space == 1)
-                                                PRINT(' ');
-                                } else if (sep_by_space == 1)
-                                        PRINT(space_char);
-                        }
-                } else if (sign_posn == 1)
-                        PRINTS(signstr);
-
-                PRINTS(asciivalue);
-
-                if (cs_precedes == 0) {
-                        if (sign_posn == 3) {
-                                if (sep_by_space == 1)
-                                        PRINT(' ');
-                                PRINTS(signstr);
-                        }
-
-                        if (!(flags & SUPRESS_CURR_SYMBOL)) {
-                                if ((sign_posn == 3 && sep_by_space == 2)
-                                    || (sep_by_space == 1
-                                    && (sign_posn == 0
-                                    || sign_posn == 1
-                                    || sign_posn == 2
-                                    || sign_posn == 4)))
-                                        PRINT(space_char);
-                                PRINTS(currency_symbol); /* XXX: len */
-                                if (sign_posn == 4) {
-                                        if (sep_by_space == 2)
-                                                PRINT(' ');
-                                        PRINTS(signstr);
-                                }
-                        }
-                }
-
-                if (sign_posn == 2) {
-                        if (sep_by_space == 2)
-                                PRINT(' ');
-                        PRINTS(signstr);
-                }
-
-                if (sign_posn == 0 && (flags & IS_NEGATIVE))
-                        PRINT(')');
-
-                if (dst - tmpptr < width) {
-                        if (flags & LEFT_JUSTIFY) {
-                                while (dst - tmpptr < width)
-                                        PRINT(' ');
-                        } else {
-                                pad_size = dst-tmpptr;
-                                memmove(tmpptr + width-pad_size, tmpptr,
-                                    pad_size);
-                                memset(tmpptr, ' ', width-pad_size);
-                                dst += width-pad_size;
-                        }
-                }
-        }
-
-        PRINT('\0');
-        va_end(ap);
-        free(asciivalue);
-        free(currency_symbol);
-        return (dst - s - 1);   /* return size of put data except trailing '\0' */
-
-e2big_error:
-        errno = E2BIG;
-        goto end_error;
-
-format_error:
-        errno = EINVAL;
-
-end_error:
-        sverrno = errno;
-        if (asciivalue != NULL)
-                free(asciivalue);
-        if (currency_symbol != NULL)
-                free(currency_symbol);
-        errno = sverrno;
-        va_end(ap);
-        return (-1);
-}
-
-static void
-__setup_vars(int flags, char *cs_precedes, char *sep_by_space,
-                char *sign_posn, char **signstr) {
-
-        struct lconv *lc = localeconv();
-
-#if defined _WIN32 && !defined __cygwin__
-        if (flags & IS_NEGATIVE) {
-#else
-        if ((flags & IS_NEGATIVE) && (flags & USE_INTL_CURRENCY)) {
-                *cs_precedes = lc->int_n_cs_precedes;
-                *sep_by_space = lc->int_n_sep_by_space;
-                *sign_posn = (flags & PARENTH_POSN) ? 0 : lc->int_n_sign_posn;
-                *signstr = (lc->negative_sign == '\0') ? "-"
-                    : lc->negative_sign;
-        } else if (flags & USE_INTL_CURRENCY) {
-                *cs_precedes = lc->int_p_cs_precedes;
-                *sep_by_space = lc->int_p_sep_by_space;
-                *sign_posn = (flags & PARENTH_POSN) ? 0 : lc->int_p_sign_posn;
-                *signstr = lc->positive_sign;
-        } else if (flags & IS_NEGATIVE) {
-#endif
-                *cs_precedes = lc->n_cs_precedes;
-                *sep_by_space = lc->n_sep_by_space;
-                *sign_posn = (flags & PARENTH_POSN) ? 0 : lc->n_sign_posn;
-                *signstr = (lc->negative_sign == NULL) ? "-"
-                    : lc->negative_sign;
-        } else {
-                *cs_precedes = lc->p_cs_precedes;
-                *sep_by_space = lc->p_sep_by_space;
-                *sign_posn = (flags & PARENTH_POSN) ? 0 : lc->p_sign_posn;
-                *signstr = lc->positive_sign;
-        }
-
-        /* Set default values for unspecified information. */
-        if (*cs_precedes != 0)
-                *cs_precedes = 1;
-        if (*sep_by_space == CHAR_MAX)
-                *sep_by_space = 0;
-        if (*sign_posn == CHAR_MAX)
-                *sign_posn = 0;
-}
-
-static int
-__calc_left_pad(int flags, char *cur_symb) {
-
-        char cs_precedes, sep_by_space, sign_posn, *signstr;
-        int left_chars = 0;
-
-        __setup_vars(flags, &cs_precedes, &sep_by_space, &sign_posn, &signstr);
-
-        if (cs_precedes != 0) {
-                left_chars += strlen(cur_symb);
-                if (sep_by_space != 0)
-                        left_chars++;
-        }
-
-        switch (sign_posn) {
-                case 1:
-                        left_chars += strlen(signstr);
-                        break;
-                case 3:
-                case 4:
-                        if (cs_precedes != 0)
-                                left_chars += strlen(signstr);
-        }
-        return (left_chars);
-}
-
-static int
-get_groups(int size, char *grouping) {
-
-        int     chars = 0;
-
-        if (*grouping == CHAR_MAX || *grouping <= 0)    /* no grouping ? */
-                return (0);
-
-        while (size > (int)*grouping) {
-                chars++;
-                size -= (int)*grouping++;
-                /* no more grouping ? */
-                if (*grouping == CHAR_MAX)
-                        break;
-                /* rest grouping with same value ? */
-                if (*grouping == 0) {
-                        chars += (size - 1) / *(grouping - 1);
-                        break;
-                }
-        }
-        return (chars);
-}
-
-#define BUFFSIZE 255
-
-/* convert double to ASCII */
-static char *
-__format_grouped_double(double value, int *flags,
-                        int left_prec, int right_prec, int pad_char) {
-
-        char            *rslt;
-        char            *avalue;
-        int             avalue_size;
-        char            fmt[32];
-
-        size_t          bufsize;
-        char            *bufend;
-
-        int             padded;
-
-        struct lconv    *lc = localeconv();
-        char            *grouping;
-        char            decimal_point;
-        char            thousands_sep;
-
-        int groups = 0;
-
-        grouping = lc->mon_grouping;
-        decimal_point = *lc->mon_decimal_point;
-        if (decimal_point == '\0')
-                decimal_point = *lc->decimal_point;
-        thousands_sep = *lc->mon_thousands_sep;
-        if (thousands_sep == '\0')
-                thousands_sep = *lc->thousands_sep;
-
-        /* fill left_prec with default value */
-        if (left_prec == -1)
-                left_prec = 0;
-
-        /* fill right_prec with default value */
-        if (right_prec == -1) {
-                if (*flags & USE_INTL_CURRENCY)
-                        right_prec = lc->int_frac_digits;
-                else
-                        right_prec = lc->frac_digits;
-
-                if (right_prec == CHAR_MAX)     /* POSIX locale ? */
-                        right_prec = 2;
-        }
-
-        if (*flags & NEED_GROUPING)
-                left_prec += get_groups(left_prec, grouping);
-
-        /* convert to string */
-        snprintf(fmt, sizeof(fmt), "%%%d.%df", left_prec + right_prec + 1,
-            right_prec);
-        avalue = malloc (BUFFSIZE);
-        if (!avalue)
-                return (NULL);
-        avalue_size = snprintf(avalue, BUFFSIZE, fmt, value);
-        if (BUFFSIZE < avalue_size)
-        {
-                avalue = realloc (avalue, avalue_size + 1);
-                if (!avalue)
-                        return (NULL);
-                avalue_size = sprintf(avalue, fmt, value);
-        }
-        if (avalue_size < 0)
-                return (NULL);
-
-        /* make sure that we've enough space for result string */
-        bufsize = strlen(avalue)*2+1;
-        rslt = malloc(bufsize);
-        if (rslt == NULL) {
-                free(avalue);
-                return (NULL);
-        }
-        memset(rslt, 0, bufsize);
-        bufend = rslt + bufsize - 1;    /* reserve space for trailing '\0' */
-
-        /* skip spaces at beginning */
-        padded = 0;
-        while (avalue[padded] == ' ') {
-                padded++;
-                avalue_size--;
-        }
-
-        if (right_prec > 0) {
-                bufend -= right_prec;
-                memcpy(bufend, avalue + avalue_size+padded-right_prec,
-                    right_prec);
-                *--bufend = decimal_point;
-                avalue_size -= (right_prec + 1);
-        }
-
-        if ((*flags & NEED_GROUPING) &&
-            thousands_sep != '\0' &&    /* XXX: need investigation */
-            *grouping != CHAR_MAX &&
-            *grouping > 0) {
-                while (avalue_size > (int)*grouping) {
-                        GRPCPY(*grouping);
-                        GRPSEP;
-                        grouping++;
-
-                        /* no more grouping ? */
-                        if (*grouping == CHAR_MAX)
-                                break;
-
-                        /* rest grouping with same value ? */
-                        if (*grouping == 0) {
-                                grouping--;
-                                while (avalue_size > *grouping) {
-                                        GRPCPY(*grouping);
-                                        GRPSEP;
-                                }
-                        }
-                }
-                if (avalue_size != 0)
-                        GRPCPY(avalue_size);
-                padded -= groups;
-
-        } else {
-                bufend -= avalue_size;
-                memcpy(bufend, avalue+padded, avalue_size);
-                if (right_prec == 0)
-                        padded--;       /* decrease assumed $decimal_point */
-        }
-
-        /* do padding with pad_char */
-        if (padded > 0) {
-                bufend -= padded;
-                memset(bufend, pad_char, padded);
-        }
-
-        bufsize = bufsize - (bufend - rslt) + 1;
-        memmove(rslt, bufend, bufsize);
-        free(avalue);
-        return (rslt);
-}
diff --git a/borrowed/libc/strfmon.h b/borrowed/libc/strfmon.h
deleted file mode 100644
index 8380450..0000000
--- a/borrowed/libc/strfmon.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*-
- * Copyright (c) 2001 Alexey Zelkin <phantom at FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- */
-#ifndef __STRFMON_H__
-#define __STRFMON_H__
-
-#ifndef HAVE_STRFMON
-/*
- * Version of "strfmon()", for the benefit of OSes that don't have it.
- */
-ssize_t
-strfmon(char * __restrict s, size_t maxsize, const char * __restrict format,
-    ...);
-
-#endif
-
-#endif
diff --git a/common/config.h.cmake.in b/common/config.h.cmake.in
index 200b129..7a0cc8a 100644
--- a/common/config.h.cmake.in
+++ b/common/config.h.cmake.in
@@ -219,9 +219,6 @@
 /* Define to 1 if you have the `stpcpy' function. */
 #cmakedefine HAVE_STPCPY 1
 
-/* Define to 1 if you have the `strfmon' function. */
-#cmakedefine HAVE_STRFMON 1
-
 /* Define to 1 if you have the <strings.h> header file. */
 #cmakedefine HAVE_STRINGS_H 1
 
diff --git a/gnucash/gnome/CMakeLists.txt b/gnucash/gnome/CMakeLists.txt
index 80c165e..3e99c19 100644
--- a/gnucash/gnome/CMakeLists.txt
+++ b/gnucash/gnome/CMakeLists.txt
@@ -123,10 +123,6 @@ set (gnc_gnome_SOURCES
 
 set_source_files_properties (${gnc_gnome_SOURCES} PROPERTIES OBJECT_DEPENDS ${CONFIG_H})
 
-if (WIN32)
-  set (gnc_gnome_SOURCES ${gnc_gnome_SOURCES} ${CMAKE_SOURCE_DIR}/borrowed/libc/strfmon.c)
-endif(WIN32)
-
 add_library (gnc-gnome ${gnc_gnome_SOURCES} ${gnc_gnome_noinst_HEADERS} ${SWIG_GNOME_C})
 target_link_libraries(gnc-gnome gncmod-gnome-search gncmod-ledger-core gncmod-report-gnome gncmod-report-system
     gncmod-register-gnome gncmod-register-core gncmod-gnome-utils gncmod-engine ${GTK3_LDFLAGS} ${GTK_MAC_LDFLAGS})
diff --git a/gnucash/gnome/assistant-loan.cpp b/gnucash/gnome/assistant-loan.cpp
index fbca2a7..00af266 100644
--- a/gnucash/gnome/assistant-loan.cpp
+++ b/gnucash/gnome/assistant-loan.cpp
@@ -47,14 +47,15 @@ extern "C"
 #include "gnc-ui-util.h"
 #include "gnc-frequency.h"
 #include "gnc-engine.h"
-
-#ifndef HAVE_STRFMON
-# include "strfmon.h"
-#else
-# include <monetary.h>
-#endif
 }
 
+#include <boost/locale.hpp>
+#include <string>
+#include <sstream>
+#include <iomanip>
+
+namespace bl = boost::locale;
+
 #define DIALOG_LOAN_ASSISTANT_CM_CLASS "assistant-loan-setup"
 
 static QofLogModule log_module = GNC_MOD_ASSISTANT;
@@ -2298,26 +2299,46 @@ gfloat loan_apr_to_simple_formula (gfloat rate, gfloat compounding_periods)
     return (simple_rate);
 }
 
-#define MAX_FORMULA 1024
+using boost::locale::conv::utf_to_utf;
+
+// Define a monetary facet template for printing monetary values
+// with a custom precision <prec>
+// This will be used to generate the loan formulas, which use 5 decimal places
+// for the loan percentage and 2 decimal places for all other numbers.
+
+// Note this facet is wchar_t based: some locales have non-ascii thousands
+// separators and these can't be handled by a char based moneypunct facet.
+
+template<int prec>
+struct cust_prec_punct : std::moneypunct_byname<wchar_t, false> {
+    cust_prec_punct(const char* name) : moneypunct_byname(name) {}
+    int do_frac_digits() const { return prec; }
+};
+
+// Convert a double to a string hardcoding <prec> decimal places
+template<int prec>
+std::string to_str_with_prec (const gdouble val)
+{
+    auto loc = std::locale(std::locale(""), new cust_prec_punct<prec>(""));
+    std::wstringstream valstr;
+    valstr.imbue(loc);
+    valstr << std::put_money(val * pow(10, prec));
+    return utf_to_utf<char>(valstr.str());
+}
 
 static
 void
-loan_get_formula_internal( LoanAssistantData *ldd, GString *gstr, const gchar* tpl )
+loan_get_formula_internal( LoanAssistantData *ldd, GString *gstr, const gchar *tpl )
 {
-    gint rate_case;
-    gfloat pass_thru_rate, period_rate;
-    gfloat periods;
-    gfloat principal;
-    gchar formula[MAX_FORMULA];
-
     g_assert( ldd != NULL );
     g_assert( gstr != NULL );
 
-    pass_thru_rate = ldd->ld.interestRate / 100;
-    periods = (ldd->ld.numPer * (ldd->ld.perSize == GNC_MONTHS ? 1 : 12)) * 1.;
-    principal = gnc_numeric_to_double(ldd->ld.principal);
+    gdouble pass_thru_rate = ldd->ld.interestRate / 100.0;
+    gdouble periods = (ldd->ld.numPer * (ldd->ld.perSize == GNC_MONTHS ? 1 : 12)) * 1.;
+    auto principal = gnc_numeric_to_double(ldd->ld.principal);
 
-    rate_case = ldd->ld.rateType;
+    gdouble period_rate;
+    auto rate_case = ldd->ld.rateType;
     switch (rate_case)
     {
     case GNC_IRATE_SIMPLE:
@@ -2343,17 +2364,29 @@ loan_get_formula_internal( LoanAssistantData *ldd, GString *gstr, const gchar* t
         break;
     }
 
-    if (0 < strfmon (formula, MAX_FORMULA, tpl,
-                     period_rate, 12.0, periods, principal ))
-        g_string_append (gstr, formula);
+    auto period_rate_str = to_str_with_prec<5> (period_rate);
+    auto period_base_str = to_str_with_prec<2> (12.0);
+    auto periods_str = to_str_with_prec<2> (periods);
+    auto principal_str = to_str_with_prec<2> (principal);
+
+    // Using boost::locale::format here to merge a template
+    // with plain strings. We can't use bl::format directly on the double
+    // values as it will use numeric punctuation instead of monetary punctuation.
+    // This is different in several locales (like nl_BE and ru_RU)
+    // and our parsing function does expect monetary punctuation to work properly.
+    // So instead of bl::format we could also have used boost::format.
+    // However at the time of this writing that sublibrary is not yet a requirement
+    // for gnucash. So I stuck with bl::format, which is.
+    auto formula = (bl::format (tpl) % period_rate_str %
+                    period_base_str % periods_str % principal_str).str();
+        g_string_append (gstr, formula.c_str());
 }
 
-
 static
 void
 loan_get_pmt_formula( LoanAssistantData *ldd, GString *gstr )
 {
-    loan_get_formula_internal (ldd, gstr, "pmt( %!.5i / %!0.2i : %!0.2i : %!0.2i : 0 : 0 )");
+    loan_get_formula_internal (ldd, gstr, "pmt( {1} / {2} : {3} : {4} : 0 : 0 )");
 }
 
 
@@ -2361,7 +2394,7 @@ static
 void
 loan_get_ppmt_formula( LoanAssistantData *ldd, GString *gstr )
 {
-    loan_get_formula_internal (ldd, gstr, "ppmt( %!.5i / %!0.2i : i : %!0.2i : %!0.2i : 0 : 0 )");
+    loan_get_formula_internal (ldd, gstr, "ppmt( {1} / {2} : i : {3} : {4} : 0 : 0 )");
 }
 
 
@@ -2369,7 +2402,7 @@ static
 void
 loan_get_ipmt_formula( LoanAssistantData *ldd, GString *gstr )
 {
-    loan_get_formula_internal (ldd, gstr, "ipmt( %!.5i / %!0.2i : i : %!0.2i : %!0.2i : 0 : 0 )");
+    loan_get_formula_internal (ldd, gstr, "ipmt( {1} / {2} : i : {3} : {4} : 0 : 0 )");
 }
 
 /******************* Scheduled Transaction Functions ********************/
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 06f9c4d..9f051b9 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -36,7 +36,6 @@ borrowed/gwengui-gtk3/w_vspacer.c
 borrowed/jenny/jenny.c
 borrowed/libc/libc-missing-noop.c
 borrowed/libc/setenv.c
-borrowed/libc/strfmon.c
 borrowed/libc/strptime.c
 doc/tip_of_the_day.list.c
 gnucash/gnome/assistant-acct-period.c

commit 34cb4925a4be639e8d3e211ce2020d2190d5a41d
Author: Geert Janssens <geert at kobaltwit.be>
Date:   Sat Aug 11 15:33:19 2018 +0200

    Compile assistant-loan as c++
    
    Fix only c++ compatibility issues, which primarily boils down
    to dealing with stricter type checking.

diff --git a/gnucash/gnome/CMakeLists.txt b/gnucash/gnome/CMakeLists.txt
index 44bd887..80c165e 100644
--- a/gnucash/gnome/CMakeLists.txt
+++ b/gnucash/gnome/CMakeLists.txt
@@ -64,7 +64,7 @@ gnc_add_swig_guile_command (swig-gnome-c
 set (gnc_gnome_SOURCES
   assistant-acct-period.c
   assistant-hierarchy.c
-  assistant-loan.c
+  assistant-loan.cpp
   assistant-stock-split.c
   business-options-gnome.c
   business-urls.c
diff --git a/gnucash/gnome/assistant-loan.c b/gnucash/gnome/assistant-loan.cpp
similarity index 94%
rename from gnucash/gnome/assistant-loan.c
rename to gnucash/gnome/assistant-loan.cpp
index 388af79..fbca2a7 100644
--- a/gnucash/gnome/assistant-loan.c
+++ b/gnucash/gnome/assistant-loan.cpp
@@ -23,6 +23,8 @@
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
 \********************************************************************/
 
+extern "C"
+{
 #include <config.h>
 #include <gtk/gtk.h>
 #include <glib/gi18n.h>
@@ -51,6 +53,8 @@
 #else
 # include <monetary.h>
 #endif
+}
+
 #define DIALOG_LOAN_ASSISTANT_CM_CLASS "assistant-loan-setup"
 
 static QofLogModule log_module = GNC_MOD_ASSISTANT;
@@ -102,8 +106,8 @@ typedef struct RepayOptData_
  **/
 typedef struct RepayOptDataDefault_
 {
-    char *name;
-    char *defaultTxnMemo;
+    const char *name;
+    const char *defaultTxnMemo;
     gboolean escrowDefault;
     gboolean specSrcAcctDefault;
 } RepayOptDataDefault;
@@ -362,10 +366,12 @@ static gint loan_find_ttsplit_with_acct( gconstpointer elt, gconstpointer crit )
 static void loan_create_sx_from_tcSX( LoanAssistantData *ldd, toCreateSX *tcSX );
 static void loan_tcSX_free( gpointer data, gpointer user_data );
 
+extern "C" {
 void loan_assistant_prepare( GtkAssistant *assistant, GtkWidget *page, gpointer user_data );
 void loan_assistant_finish( GtkAssistant *gtkassistant, gpointer user_data );
 void loan_assistant_cancel( GtkAssistant *gtkassistant, gpointer user_data );
 void loan_assistant_close( GtkAssistant *gtkassistant, gpointer user_data );
+}
 
 /*****************************************************************************/
 
@@ -374,7 +380,7 @@ static
 void
 loan_assistant_close_handler( gpointer user_data )
 {
-    LoanAssistantData *ldd = user_data;
+    LoanAssistantData *ldd = static_cast<LoanAssistantData*> (user_data);
     gtk_widget_destroy( ldd->window );
 }
 
@@ -383,7 +389,7 @@ static
 void
 loan_assistant_window_destroy_cb( GtkWidget *object, gpointer user_data )
 {
-    LoanAssistantData *ldd = user_data;
+    LoanAssistantData *ldd = static_cast<LoanAssistantData*> (user_data);
 
     g_assert( ldd );
 
@@ -951,7 +957,7 @@ static
 void
 loan_info_prep( GtkAssistant *assistant, gpointer user_data )
 {
-    LoanAssistantData *ldd = user_data;
+    LoanAssistantData *ldd = static_cast<LoanAssistantData*> (user_data);
 
     gnc_amount_edit_set_amount( ldd->prmOrigPrincGAE, ldd->ld.principal );
     gtk_spin_button_set_value( ldd->prmIrateSpin, ldd->ld.interestRate );
@@ -959,9 +965,11 @@ loan_info_prep( GtkAssistant *assistant, gpointer user_data )
     gtk_combo_box_set_active( ldd->prmType, ldd->ld.type );
     if ( ldd->ld.type != GNC_FIXED )
     {
-        g_signal_handlers_block_by_func( GNC_FREQUENCY( ldd->prmVarGncFreq), loan_info_page_valid_cb , ldd );
+        g_signal_handlers_block_by_func( GNC_FREQUENCY( ldd->prmVarGncFreq),
+                                         (gpointer) loan_info_page_valid_cb, ldd );
         gnc_frequency_setup_recurrence(ldd->prmVarGncFreq, ldd->ld.loan_schedule, ldd->ld.varStartDate);
-        g_signal_handlers_unblock_by_func( GNC_FREQUENCY( ldd->prmVarGncFreq), loan_info_page_valid_cb , ldd );
+        g_signal_handlers_unblock_by_func( GNC_FREQUENCY( ldd->prmVarGncFreq),
+                                           (gpointer) loan_info_page_valid_cb, ldd );
     }
 
     /* start date */
@@ -989,7 +997,7 @@ static
 void
 loan_info_prm_type_cb( GtkWidget *w, gpointer user_data )
 {
-    LoanAssistantData *ldd = user_data;
+    LoanAssistantData *ldd = static_cast<LoanAssistantData*> (user_data);
     gint index;
 
     index = gtk_combo_box_get_active( ldd->prmType );
@@ -1002,7 +1010,7 @@ static
 void
 loan_info_calc_update_cb( GtkWidget *w, gpointer user_data )
 {
-    LoanAssistantData *ldd = user_data;
+    LoanAssistantData *ldd = static_cast<LoanAssistantData*> (user_data);
     GDate start, now;
     int i, totalVal, total, remain;
 
@@ -1034,7 +1042,7 @@ loan_info_calc_update_cb( GtkWidget *w, gpointer user_data )
 void
 loan_info_page_valid_cb (GtkWidget *widget, gpointer user_data )
 {
-    LoanAssistantData *ldd = user_data;
+    LoanAssistantData *ldd = static_cast<LoanAssistantData*> (user_data);
     GtkAssistant *assistant = GTK_ASSISTANT(ldd->window);
     gint num = gtk_assistant_get_current_page (assistant);
     GtkWidget *page = gtk_assistant_get_nth_page (assistant, num);
@@ -1048,7 +1056,7 @@ static
 gboolean
 loan_info_page_complete( GtkAssistant *assistant, gpointer user_data )
 {
-    LoanAssistantData *ldd = user_data;
+    LoanAssistantData *ldd = static_cast<LoanAssistantData*> (user_data);
 
     ldd->ld.primaryAcct = gnc_account_sel_get_account( ldd->prmAccountGAS );
     /* Test for valid Account */
@@ -1063,7 +1071,7 @@ static
 void
 loan_info_page_save( GtkAssistant *assistant, gpointer user_data )
 {
-    LoanAssistantData *ldd = user_data;
+    LoanAssistantData *ldd = static_cast<LoanAssistantData*> (user_data);
 
     ldd->ld.primaryAcct = gnc_account_sel_get_account( ldd->prmAccountGAS );
 
@@ -1073,8 +1081,8 @@ loan_info_page_save( GtkAssistant *assistant, gpointer user_data )
     }
     ldd->ld.principal = gnc_amount_edit_get_amount( ldd->prmOrigPrincGAE );
     ldd->ld.interestRate = gtk_spin_button_get_value( ldd->prmIrateSpin );
-    ldd->ld.rateType = gtk_combo_box_get_active (ldd->prmIrateType );
-    ldd->ld.type = gtk_combo_box_get_active( ldd->prmType );
+    ldd->ld.rateType = static_cast<IRateType>( gtk_combo_box_get_active (ldd->prmIrateType ));
+    ldd->ld.type = static_cast<LoanType>( gtk_combo_box_get_active( ldd->prmType ));
 
     if ( ldd->ld.type != GNC_FIXED )
     {
@@ -1095,7 +1103,7 @@ loan_info_page_save( GtkAssistant *assistant, gpointer user_data )
         {
             g_date_set_dmy( ldd->ld.startDate,
                             tmpTm->tm_mday,
-                            (tmpTm->tm_mon + 1),
+                            static_cast<GDateMonth>(tmpTm->tm_mon + 1),
                             (1900 + tmpTm->tm_year) );
             gnc_tm_free (tmpTm);
         }
@@ -1121,7 +1129,7 @@ loan_opt_prep( GtkAssistant *assistant, gpointer user_data )
 {
     int i;
     RepayOptUIData *rouid;
-    LoanAssistantData *ldd = user_data;
+    LoanAssistantData *ldd = static_cast<LoanAssistantData*> (user_data);
 
     /* Save Previous Page ( Information ) */
     loan_info_page_save(assistant, ldd);
@@ -1190,7 +1198,7 @@ loan_opt_escrow_toggle_cb( GtkToggleButton *tb, gpointer user_data )
     int i;
     gboolean newState;
     RepayOptUIData *rouid;
-    LoanAssistantData *ldd = user_data;
+    LoanAssistantData *ldd = static_cast<LoanAssistantData*> (user_data);
     GtkAssistant *assistant = GTK_ASSISTANT(ldd->window);
     gint num = gtk_assistant_get_current_page (assistant);
     GtkWidget *page = gtk_assistant_get_nth_page (assistant, num);
@@ -1221,7 +1229,7 @@ loan_opt_escrow_toggle_cb( GtkToggleButton *tb, gpointer user_data )
         /* prevent the toggle handler from running and "trashing" the
          * state of the throughEscrowP selection */
         g_signal_handlers_block_by_func( rouid->escrowCb,
-                                         loan_opt_escrow_toggled_cb,
+                                         (gpointer) loan_opt_escrow_toggled_cb,
                                          rouid );
         gtk_toggle_button_set_active(
             GTK_TOGGLE_BUTTON(rouid->escrowCb),
@@ -1233,7 +1241,7 @@ loan_opt_escrow_toggle_cb( GtkToggleButton *tb, gpointer user_data )
             newState
             && gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(rouid->optCb) ) );
         g_signal_handlers_unblock_by_func( rouid->escrowCb,
-                                           loan_opt_escrow_toggled_cb,
+                                           (gpointer) loan_opt_escrow_toggled_cb,
                                            rouid );
         if ( newState )
         {
@@ -1261,7 +1269,7 @@ loan_opt_escrow_toggled_cb( GtkToggleButton *tb, gpointer user_data )
 void
 loan_opt_page_valid_cb (GtkWidget *widget, gpointer user_data )
 {
-    LoanAssistantData *ldd = user_data;
+    LoanAssistantData *ldd = static_cast<LoanAssistantData*> (user_data);
 
     GtkAssistant *assistant = GTK_ASSISTANT(ldd->window);
     gint num = gtk_assistant_get_current_page (assistant);
@@ -1276,7 +1284,7 @@ static
 gboolean
 loan_opt_page_complete( GtkAssistant *assistant, gpointer user_data )
 {
-    LoanAssistantData *ldd = user_data;
+    LoanAssistantData *ldd = static_cast<LoanAssistantData*> (user_data);
 
     if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(ldd->optEscrowCb) ) )
     {
@@ -1299,7 +1307,7 @@ static
 void
 loan_rep_prep( GtkAssistant *assistant, gpointer user_data )
 {
-    LoanAssistantData *ldd = user_data;
+    LoanAssistantData *ldd = static_cast<LoanAssistantData*> (user_data);
     GString *str;
 
     if ( ldd->ld.repAmount )
@@ -1322,9 +1330,11 @@ loan_rep_prep( GtkAssistant *assistant, gpointer user_data )
     gnc_account_sel_set_account( ldd->repPrincToGAS, ldd->ld.repPriAcct, FALSE );
     gnc_account_sel_set_account( ldd->repIntToGAS, ldd->ld.repIntAcct, FALSE );
 
-    g_signal_handlers_block_by_func( ldd->repGncFreq, loan_rep_page_valid_cb , ldd );
+    g_signal_handlers_block_by_func( ldd->repGncFreq,
+                                     (gpointer) loan_rep_page_valid_cb, ldd );
     gnc_frequency_setup_recurrence(ldd->repGncFreq, ldd->ld.repayment_schedule, ldd->ld.repStartDate);
-    g_signal_handlers_unblock_by_func( ldd->repGncFreq, loan_rep_page_valid_cb , ldd );
+    g_signal_handlers_unblock_by_func( ldd->repGncFreq,
+                                       (gpointer) loan_rep_page_valid_cb, ldd );
 
     /* Find the first enabled option */
     {
@@ -1345,7 +1355,7 @@ loan_rep_prep( GtkAssistant *assistant, gpointer user_data )
 void
 loan_rep_page_valid_cb (GtkWidget *widget, gpointer user_data )
 {
-    LoanAssistantData *ldd = user_data;
+    LoanAssistantData *ldd = static_cast<LoanAssistantData*> (user_data);
     GtkAssistant *assistant = GTK_ASSISTANT(ldd->window);
     gint num = gtk_assistant_get_current_page (assistant);
     GtkWidget *page = gtk_assistant_get_nth_page (assistant, num);
@@ -1359,7 +1369,7 @@ static
 gboolean
 loan_rep_page_complete( GtkAssistant *assistant, gpointer user_data )
 {
-    LoanAssistantData *ldd = user_data;
+    LoanAssistantData *ldd = static_cast<LoanAssistantData*> (user_data);
 
     ldd->ld.repFromAcct =
         gnc_account_sel_get_account( ldd->repAssetsFromGAS );
@@ -1387,7 +1397,7 @@ static
 void
 loan_rep_page_save( GtkAssistant *assistant, gpointer user_data )
 {
-    LoanAssistantData *ldd = user_data;
+    LoanAssistantData *ldd = static_cast<LoanAssistantData*> (user_data);
 
     if ( ldd->ld.repMemo )
         g_free( ldd->ld.repMemo );
@@ -1420,7 +1430,7 @@ static
 void
 loan_pay_prep( GtkAssistant *assistant, gpointer user_data )
 {
-    LoanAssistantData *ldd = user_data;
+    LoanAssistantData *ldd = static_cast<LoanAssistantData*> (user_data);
     RepayOptData *rod;
     GString *str;
 
@@ -1457,7 +1467,7 @@ loan_pay_prep( GtkAssistant *assistant, gpointer user_data )
 
         {
             g_signal_handlers_block_by_func( ldd->payUseEscrow,
-                                             loan_pay_use_esc_toggle_cb,
+                                             (gpointer) loan_pay_use_esc_toggle_cb,
                                              ldd );
 
             loan_pay_use_esc_setup( ldd,
@@ -1468,38 +1478,43 @@ loan_pay_prep( GtkAssistant *assistant, gpointer user_data )
                                            && ldd->ld.escrowAcct != NULL) );
 
             g_signal_handlers_unblock_by_func( ldd->payUseEscrow,
-                                               loan_pay_use_esc_toggle_cb,
+                                               (gpointer) loan_pay_use_esc_toggle_cb,
                                                ldd );
         }
 
         {
             g_signal_handlers_block_by_func( ldd->paySpecSrcAcct,
-                                             loan_pay_spec_src_toggle_cb,
+                                             (gpointer) loan_pay_spec_src_toggle_cb,
                                              ldd );
             loan_pay_spec_src_setup( ldd, rod->specSrcAcctP );
             gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(ldd->paySpecSrcAcct),
                                           rod->specSrcAcctP );
 
             g_signal_handlers_unblock_by_func( ldd->paySpecSrcAcct,
-                                               loan_pay_spec_src_toggle_cb,
+                                               (gpointer) loan_pay_spec_src_toggle_cb,
                                                ldd );
         }
 
-        g_signal_handlers_block_by_func(ldd->payAcctToGAS, loan_pay_page_valid_cb, ldd );
+        g_signal_handlers_block_by_func(ldd->payAcctToGAS,
+                                        (gpointer) loan_pay_page_valid_cb, ldd );
         gnc_account_sel_set_account( ldd->payAcctToGAS,   rod->to, FALSE );
-        g_signal_handlers_unblock_by_func(ldd->payAcctToGAS, loan_pay_page_valid_cb, ldd );
+        g_signal_handlers_unblock_by_func(ldd->payAcctToGAS,
+                                          (gpointer) loan_pay_page_valid_cb, ldd );
 
 
-        g_signal_handlers_block_by_func(ldd->payTxnFreqUniqRb, loan_pay_freq_toggle_cb, ldd );
+        g_signal_handlers_block_by_func(ldd->payTxnFreqUniqRb,
+                                        (gpointer) loan_pay_freq_toggle_cb, ldd );
         gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(ldd->payTxnFreqPartRb), !rod->FreqUniq );
         gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(ldd->payTxnFreqUniqRb), rod->FreqUniq );
-        g_signal_handlers_unblock_by_func(ldd->payTxnFreqUniqRb, loan_pay_freq_toggle_cb, ldd );
+        g_signal_handlers_unblock_by_func(ldd->payTxnFreqUniqRb,
+                                          (gpointer) loan_pay_freq_toggle_cb, ldd );
 
         gtk_widget_set_sensitive( GTK_WIDGET(ldd->payFreqHBox), rod->FreqUniq );
 
         if ( rod->FreqUniq )
         {
-            g_signal_handlers_disconnect_by_func( ldd->payGncFreq, loan_pay_page_valid_cb, ldd );
+            g_signal_handlers_disconnect_by_func( ldd->payGncFreq,
+                                                  (gpointer) loan_pay_page_valid_cb, ldd );
             gtk_container_remove( GTK_CONTAINER(ldd->payFreqHBox), GTK_WIDGET(ldd->payGncFreq) );
             ldd->payGncFreq = NULL;
             ldd->payGncFreq = GNC_FREQUENCY(gnc_frequency_new_from_recurrence( rod->schedule, rod->startDate ));
@@ -1516,7 +1531,7 @@ loan_pay_prep( GtkAssistant *assistant, gpointer user_data )
 void
 loan_pay_page_valid_cb (GtkWidget *widget, gpointer user_data )
 {
-    LoanAssistantData *ldd = user_data;
+    LoanAssistantData *ldd = static_cast<LoanAssistantData*> (user_data);
     GtkAssistant *assistant = GTK_ASSISTANT(ldd->window);
     gint num = gtk_assistant_get_current_page (assistant);
     GtkWidget *page = gtk_assistant_get_nth_page (assistant, num);
@@ -1535,12 +1550,16 @@ loan_pay_use_esc_setup( LoanAssistantData *ldd, gboolean newState )
     gtk_widget_set_sensitive( GTK_WIDGET(ldd->payEscFromLabel), newState );
     if ( newState )
     {
-        g_signal_handlers_block_by_func( ldd->payAcctEscToGAS, loan_pay_page_valid_cb, ldd );
-        g_signal_handlers_block_by_func( ldd->payAcctEscFromGAS, loan_pay_page_valid_cb, ldd );
+        g_signal_handlers_block_by_func( ldd->payAcctEscToGAS,
+                                         (gpointer) loan_pay_page_valid_cb, ldd );
+        g_signal_handlers_block_by_func( ldd->payAcctEscFromGAS,
+                                         (gpointer) loan_pay_page_valid_cb, ldd );
         gnc_account_sel_set_account( ldd->payAcctEscToGAS, ldd->ld.escrowAcct, FALSE );
         gnc_account_sel_set_account( ldd->payAcctEscFromGAS, ldd->ld.escrowAcct, FALSE );
-        g_signal_handlers_unblock_by_func( ldd->payAcctEscToGAS, loan_pay_page_valid_cb, ldd );
-        g_signal_handlers_unblock_by_func( ldd->payAcctEscFromGAS, loan_pay_page_valid_cb, ldd );
+        g_signal_handlers_unblock_by_func( ldd->payAcctEscToGAS,
+                                           (gpointer) loan_pay_page_valid_cb, ldd );
+        g_signal_handlers_unblock_by_func( ldd->payAcctEscFromGAS,
+                                           (gpointer) loan_pay_page_valid_cb, ldd );
     }
 }
 
@@ -1550,7 +1569,7 @@ void
 loan_pay_use_esc_toggle_cb( GtkToggleButton *tb, gpointer user_data )
 {
     gboolean newState;
-    LoanAssistantData *ldd = user_data;
+    LoanAssistantData *ldd = static_cast<LoanAssistantData*> (user_data);
 
     newState = gtk_toggle_button_get_active( tb );
     loan_pay_use_esc_setup( ldd, newState );
@@ -1565,16 +1584,20 @@ loan_pay_spec_src_setup( LoanAssistantData *ldd, gboolean newState )
     gtk_widget_set_sensitive( GTK_WIDGET(ldd->payAcctFromGAS), newState );
     if ( newState )
     {
-        g_signal_handlers_block_by_func( ldd->payAcctFromGAS, loan_pay_page_valid_cb, ldd );
+        g_signal_handlers_block_by_func( ldd->payAcctFromGAS,
+                                         (gpointer) loan_pay_page_valid_cb, ldd );
         gnc_account_sel_set_account( ldd->payAcctFromGAS, ldd->ld.repayOpts[ldd->currentIdx]->from, FALSE );
-        g_signal_handlers_unblock_by_func( ldd->payAcctFromGAS, loan_pay_page_valid_cb, ldd );
+        g_signal_handlers_unblock_by_func( ldd->payAcctFromGAS,
+                                           (gpointer) loan_pay_page_valid_cb, ldd );
     }
     else
     {
-        g_signal_handlers_block_by_func( ldd->payAcctFromGAS, loan_pay_page_valid_cb, ldd );
+        g_signal_handlers_block_by_func( ldd->payAcctFromGAS,
+                                         (gpointer) loan_pay_page_valid_cb, ldd );
         gnc_account_sel_set_account( ldd->payAcctFromGAS, NULL, FALSE );
         ldd->ld.repayOpts[ldd->currentIdx]->from = NULL;
-        g_signal_handlers_unblock_by_func( ldd->payAcctFromGAS, loan_pay_page_valid_cb, ldd );
+        g_signal_handlers_unblock_by_func( ldd->payAcctFromGAS,
+                                           (gpointer) loan_pay_page_valid_cb, ldd );
     }
 }
 
@@ -1584,7 +1607,7 @@ void
 loan_pay_spec_src_toggle_cb( GtkToggleButton *tb, gpointer user_data )
 {
     gboolean newState;
-    LoanAssistantData *ldd = user_data;
+    LoanAssistantData *ldd = static_cast<LoanAssistantData*> (user_data);
 
     newState = gtk_toggle_button_get_active( tb );
     loan_pay_spec_src_setup( ldd, newState );
@@ -1595,7 +1618,7 @@ static
 void
 loan_pay_freq_toggle_cb( GtkToggleButton *tb, gpointer user_data )
 {
-    LoanAssistantData *ldd = user_data;
+    LoanAssistantData *ldd = static_cast<LoanAssistantData*> (user_data);
     RepayOptData *rod;
 
     g_assert( ldd->currentIdx >= 0 );
@@ -1620,9 +1643,11 @@ loan_pay_freq_toggle_cb( GtkToggleButton *tb, gpointer user_data )
             rod->startDate = g_date_new();
             *rod->startDate = *ldd->ld.startDate;
         }
-        g_signal_handlers_block_by_func( ldd->payGncFreq, loan_pay_page_valid_cb, ldd );
+        g_signal_handlers_block_by_func( ldd->payGncFreq,
+                                         (gpointer) loan_pay_page_valid_cb, ldd );
         gnc_frequency_setup_recurrence(ldd->payGncFreq, rod->schedule, rod->startDate);
-        g_signal_handlers_unblock_by_func( ldd->payGncFreq, loan_pay_page_valid_cb, ldd );
+        g_signal_handlers_unblock_by_func( ldd->payGncFreq,
+                                           (gpointer) loan_pay_page_valid_cb, ldd );
     }
     else
     {
@@ -1644,7 +1669,7 @@ void
 loan_pay_next_button_cb( GtkButton *button, gpointer user_data )
 {
     int i;
-    LoanAssistantData *ldd = user_data;
+    LoanAssistantData *ldd = static_cast<LoanAssistantData*> (user_data);
 
     /* save current data */
     if ( loan_pay_complete ( GTK_ASSISTANT(ldd->window), user_data ) != FALSE )
@@ -1668,7 +1693,7 @@ void
 loan_pay_back_button_cb( GtkButton *button, gpointer user_data )
 {
     int i;
-    LoanAssistantData *ldd = user_data;
+    LoanAssistantData *ldd = static_cast<LoanAssistantData*> (user_data);
 
     /* save current data */
     if ( loan_pay_complete ( GTK_ASSISTANT(ldd->window), user_data ) != FALSE)
@@ -1691,7 +1716,7 @@ static
 gboolean
 loan_pay_all_opt_valid ( GtkAssistant *assistant, gpointer user_data )
 {
-    LoanAssistantData *ldd = user_data;
+    LoanAssistantData *ldd = static_cast<LoanAssistantData*> (user_data);
     int i;
     gboolean all_valid;
     all_valid = FALSE;
@@ -1716,7 +1741,7 @@ gboolean
 loan_pay_complete( GtkAssistant *assistant, gpointer user_data )
 {
     gchar *tmpStr;
-    LoanAssistantData *ldd = user_data;
+    LoanAssistantData *ldd = static_cast<LoanAssistantData*> (user_data);
     RepayOptData *rod;
 
     g_assert( ldd->currentIdx >= 0 );
@@ -1783,7 +1808,7 @@ loan_rev_prep( GtkAssistant *assistant, gpointer user_data )
 {
     /* 3, here, does not include the Date column. */
     static const int BASE_COLS = 3;
-    LoanAssistantData *ldd = user_data;
+    LoanAssistantData *ldd = static_cast<LoanAssistantData*> (user_data);
     GtkListStore *store;
     GtkCellRenderer *renderer;
     GtkTreeViewColumn *column;
@@ -1892,7 +1917,7 @@ static
 void
 loan_rev_range_opt_changed_cb( GtkComboBox *combo, gpointer user_data )
 {
-    LoanAssistantData *ldd = user_data;
+    LoanAssistantData *ldd = static_cast<LoanAssistantData*> (user_data);
     int opt;
 
     opt = gtk_combo_box_get_active( ldd->revRangeOpt );
@@ -1912,7 +1937,7 @@ static
 void
 loan_rev_range_changed_cb( GNCDateEdit *gde, gpointer user_data )
 {
-    LoanAssistantData *ldd = user_data;
+    LoanAssistantData *ldd = static_cast<LoanAssistantData*> (user_data);
     {
         GDate start, end;
         g_date_clear( &start, 1 );
@@ -2085,7 +2110,7 @@ loan_rev_recalc_schedule( LoanAssistantData *ldd )
             /* evaluate the expressions given the correct
              * sequence number i */
             ival = gnc_numeric_create( i, 1 );
-            g_hash_table_insert( ivar, "i", &ival );
+            g_hash_table_insert( ivar, (gpointer) "i", &ival );
 
             if ( ! gnc_exp_parser_parse_separate_vars(
                         pmtFormula->str, &val, &eloc, ivar ) )
@@ -2207,7 +2232,7 @@ static
 void
 loan_rev_update_view( LoanAssistantData *ldd, GDate *start, GDate *end )
 {
-    static gchar *NO_AMT_CELL_TEXT = " ";
+    static const gchar *NO_AMT_CELL_TEXT = " ";
     GList *l;
     GNCPrintAmountInfo pai;
     GtkListStore *store;
@@ -2277,7 +2302,7 @@ gfloat loan_apr_to_simple_formula (gfloat rate, gfloat compounding_periods)
 
 static
 void
-loan_get_formula_internal( LoanAssistantData *ldd, GString *gstr, const gchar* template )
+loan_get_formula_internal( LoanAssistantData *ldd, GString *gstr, const gchar* tpl )
 {
     gint rate_case;
     gfloat pass_thru_rate, period_rate;
@@ -2318,7 +2343,7 @@ loan_get_formula_internal( LoanAssistantData *ldd, GString *gstr, const gchar* t
         break;
     }
 
-    if (0 < strfmon (formula, MAX_FORMULA, template,
+    if (0 < strfmon (formula, MAX_FORMULA, tpl,
                      period_rate, 12.0, periods, principal ))
         g_string_append (gstr, formula);
 }
@@ -2944,7 +2969,7 @@ loan_create_sxes( LoanAssistantData *ldd )
 void
 loan_assistant_finish ( GtkAssistant *gtkassistant, gpointer user_data )
 {
-    LoanAssistantData *ldd = user_data;
+    LoanAssistantData *ldd = static_cast<LoanAssistantData*> (user_data);
     loan_create_sxes( ldd );
 
 }
@@ -2953,7 +2978,7 @@ loan_assistant_finish ( GtkAssistant *gtkassistant, gpointer user_data )
 void
 loan_assistant_cancel( GtkAssistant *gtkassistant, gpointer user_data )
 {
-    LoanAssistantData *ldd = user_data;
+    LoanAssistantData *ldd = static_cast<LoanAssistantData*> (user_data);
     gnc_close_gui_component_by_data( DIALOG_LOAN_ASSISTANT_CM_CLASS, ldd );
 }
 
@@ -2961,7 +2986,7 @@ loan_assistant_cancel( GtkAssistant *gtkassistant, gpointer user_data )
 void
 loan_assistant_close( GtkAssistant *gtkassistant, gpointer user_data )
 {
-    LoanAssistantData *ldd = user_data;
+    LoanAssistantData *ldd = static_cast<LoanAssistantData*> (user_data);
     gnc_close_gui_component_by_data( DIALOG_LOAN_ASSISTANT_CM_CLASS, ldd );
 }
 
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 386ea54..06f9c4d 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -41,7 +41,7 @@ borrowed/libc/strptime.c
 doc/tip_of_the_day.list.c
 gnucash/gnome/assistant-acct-period.c
 gnucash/gnome/assistant-hierarchy.c
-gnucash/gnome/assistant-loan.c
+gnucash/gnome/assistant-loan.cpp
 gnucash/gnome/assistant-stock-split.c
 gnucash/gnome/business-gnome-utils.c
 gnucash/gnome/business-options-gnome.c



Summary of changes:
 CMakeLists.txt                                     |   1 -
 borrowed/libc/CMakeLists.txt                       |   6 +-
 borrowed/libc/strfmon.c                            | 619 ---------------------
 borrowed/libc/strfmon.h                            |  40 --
 common/config.h.cmake.in                           |   3 -
 gnucash/gnome/CMakeLists.txt                       |   6 +-
 .../gnome/{assistant-loan.c => assistant-loan.cpp} | 232 +++++---
 po/POTFILES.in                                     |   3 +-
 8 files changed, 150 insertions(+), 760 deletions(-)
 delete mode 100644 borrowed/libc/strfmon.c
 delete mode 100644 borrowed/libc/strfmon.h
 rename gnucash/gnome/{assistant-loan.c => assistant-loan.cpp} (92%)



More information about the gnucash-changes mailing list