git: 947efadc3d6e - main - strfmon: Fix alignment when enclosed by parentheses

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

URL: https://cgit.FreeBSD.org/src/commit/?id=947efadc3d6e778a824618d82f53f061bec69b77

commit 947efadc3d6e778a824618d82f53f061bec69b77
Author:     Jose Luis Duran <jlduran@gmail.com>
AuthorDate: 2022-10-14 23:26:32 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2022-10-25 21:40:17 +0000

    strfmon: Fix alignment when enclosed by parentheses
    
    Take into consideration the possibility of quantities enclosed by
    parentheses when aligning.
    
    Matches the examples from The Open Group's:
    
    Format  Before          After
    %(#5n   [$   123.45]    [ $   123.45 ]  Use an alternative pos/neg style
            [($   123.45)]  [($   123.45)]
            [$ 3,456.78]    [ $ 3,456.78 ]
    
    %!(#5n  [   123.45]     [    123.45 ]   Disable the currency symbol
            [(   123.45)]   [(   123.45)]
            [ 3,456.78]     [  3,456.78 ]
    
    https://pubs.opengroup.org/onlinepubs/9699919799/functions/strfmon.html
    
    SD5-XSH-ERN-29 is applied, updating the examples for %(#5n and %!(#5n.
    
    Obtained from:  Darwin
    Reviewed by:    kib
    PR:     267282
    Github PR:      #619
    MFC after:      1 week
---
 lib/libc/stdlib/strfmon.c            | 12 ++++++++++--
 lib/libc/tests/stdlib/strfmon_test.c |  4 ++--
 2 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/lib/libc/stdlib/strfmon.c b/lib/libc/stdlib/strfmon.c
index a7a48317c97c..80a73ee28916 100644
--- a/lib/libc/stdlib/strfmon.c
+++ b/lib/libc/stdlib/strfmon.c
@@ -373,8 +373,12 @@ vstrfmon_l(char * __restrict s, size_t maxsize, locale_t loc,
 			PRINTS(signstr);
 		}
 
-		if (sign_posn == 0 && (flags & IS_NEGATIVE))
-			PRINT(')');
+		if (sign_posn == 0) {
+			if (flags & IS_NEGATIVE)
+				PRINT(')');
+			else if (left_prec >= 0)
+				PRINT(' ');
+		}
 
 		if (dst - tmpptr < width) {
 			if (flags & LEFT_JUSTIFY) {
@@ -466,6 +470,10 @@ __calc_left_pad(int flags, char *cur_symb)
 	}
 
 	switch (sign_posn) {
+		case 0:
+			if (flags & IS_NEGATIVE)
+				left_chars++;
+			break;
 		case 1:
 			left_chars += strlen(signstr);
 			break;
diff --git a/lib/libc/tests/stdlib/strfmon_test.c b/lib/libc/tests/stdlib/strfmon_test.c
index b5b22f9a483d..d4d1f6a580d9 100644
--- a/lib/libc/tests/stdlib/strfmon_test.c
+++ b/lib/libc/tests/stdlib/strfmon_test.c
@@ -81,8 +81,8 @@ ATF_TC_BODY(strfmon_examples, tc)
 	    { "%^#5n", "[ $  123.45] [-$  123.45] [ $ 3456.78]" },
 	    { "%^#5.0n", "[ $  123] [-$  123] [ $ 3457]" },
 	    { "%^#5.4n", "[ $  123.4500] [-$  123.4500] [ $ 3456.7810]" },
-	    { "%(#5n", "[$   123.45] [($   123.45)] [$ 3,456.78]" }, /* XXX */
-	    { "%!(#5n", "[   123.45] [(   123.45)] [ 3,456.78]" }, /* XXX */
+	    { "%(#5n", "[ $   123.45 ] [($   123.45)] [ $ 3,456.78 ]" },
+	    { "%!(#5n", "[    123.45 ] [(   123.45)] [  3,456.78 ]" },
 	    { "%-14#5.4n", "[ $   123.4500 ] [-$   123.4500 ] [ $ 3,456.7810 ]" },
 	    { "%14#5.4n", "[  $   123.4500] [ -$   123.4500] [  $ 3,456.7810]" },
 	};