git: 750fe3e6a461 - main - strfmon: Fix an edge case when sep_by_space is 2

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Tue, 25 Oct 2022 21:51:28 UTC
The branch main has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=750fe3e6a4619e040c7b0951775698b61290102e

commit 750fe3e6a4619e040c7b0951775698b61290102e
Author:     Jose Luis Duran <jlduran@gmail.com>
AuthorDate: 2022-10-18 02:24:03 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2022-10-25 21:40:17 +0000

    strfmon: Fix an edge case when sep_by_space is 2
    
    Fix an edge case by printing the required space when, the currency
    symbol succeeds the value, a space separates the sign from the value and
    the sign position precedes the quantity and the currency symbol.
    
    In other words:
    
        n_cs_precedes = 0
        n_sep_by_space = 2
        n_sign_posn = 1
    
    From The Open Group's localeconv[1]:
    
    > When {p,n,int_p,int_n}_sep_by_space is 2:
    > If the currency symbol and sign string are adjacent, a space separates
    > them; otherwise, a space separates the sign string from the value.
    
        Format    Before        After
        [%n]      [-123.45¤]    [- 123.45¤]
    
    [1]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/localeconv.html
    
    Obtained from:  Darwin
    Reviewed by:    kib
    PR:     267282
    Github PR:      #619
    MFC after:      1 week
---
 lib/libc/stdlib/strfmon.c            | 8 ++++++--
 lib/libc/tests/stdlib/strfmon_test.c | 2 +-
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/lib/libc/stdlib/strfmon.c b/lib/libc/stdlib/strfmon.c
index 80a73ee28916..d453b7a3943b 100644
--- a/lib/libc/stdlib/strfmon.c
+++ b/lib/libc/stdlib/strfmon.c
@@ -296,7 +296,8 @@ vstrfmon_l(char * __restrict s, size_t maxsize, locale_t loc,
 		 *       non-negative value
 		 * = 1 - space separates the symbol from the value
 		 * = 2 - space separates the symbol and the sign string,
-		 *       if adjacent.
+		 *       if adjacent; otherwise, a space separates
+		 *       the sign string from the value
 		 *
 		 * p_sign_posn & n_sign_posn
 		 *
@@ -338,8 +339,11 @@ vstrfmon_l(char * __restrict s, size_t maxsize, locale_t loc,
 				} else if (sep_by_space == 1)
 					PRINT(space_char);
 			}
-		} else if (sign_posn == 1)
+		} else if (sign_posn == 1) {
 			PRINTS(signstr);
+			if (sep_by_space == 2)
+				PRINT(' ');
+		}
 
 		PRINTS(asciivalue);
 
diff --git a/lib/libc/tests/stdlib/strfmon_test.c b/lib/libc/tests/stdlib/strfmon_test.c
index d4d1f6a580d9..664d1811dc46 100644
--- a/lib/libc/tests/stdlib/strfmon_test.c
+++ b/lib/libc/tests/stdlib/strfmon_test.c
@@ -116,7 +116,7 @@ ATF_TC_BODY(strfmon_cs_precedes_0, tc)
 	    /* sep_by_space x sign_posn */
 	    { "[(123.00$)] [-123.00$] [123.00$-] [123.00-$] [123.00$-]" },
 	    { "[(123.00 $)] [-123.00 $] [123.00 $-] [123.00 -$] [123.00 $-]" },
-	    { "[(123.00$)] [-123.00$] [123.00$ -] [123.00- $] [123.00$ -]" }, /* XXX */
+	    { "[(123.00$)] [- 123.00$] [123.00$ -] [123.00- $] [123.00$ -]" },
 	};
 	size_t i, j;
 	struct lconv *lc;