@@ -39,7 +39,12 @@ public static RuntimeScalar sprintf(RuntimeScalar runtimeScalar, RuntimeList lis
3939 // Check if invalid
4040 if (!spec .isValid ) {
4141 result .append (spec .raw );
42- result .append (" " ).append (spec .errorMessage );
42+ // Don't append error message for space-containing formats
43+ if (!spec .raw .matches ("%\\ d+\\ .\\ s+\\ d+[a-zA-Z]" ) &&
44+ !spec .raw .matches ("%\\ d+\\ s+\\ .\\ d+[a-zA-Z]" ) &&
45+ !spec .raw .matches ("%\\ d+\\ .\\ d+\\ s+[a-zA-Z]" )) {
46+ result .append (" " ).append (spec .errorMessage );
47+ }
4348 continue ;
4449 }
4550
@@ -296,15 +301,17 @@ private static String formatValue(RuntimeScalar value, String flags, int width,
296301 case 'u' , 'U' -> // Synonym for %u
297302 formatUnsigned (value , flags , width , precision );
298303 case 'o' , 'O' -> // Synonym for %o
299- formatInteger (value .getLong (), flags , width , precision , 8 , flags .contains ("#" ));
300- case 'x' -> formatInteger (value .getLong (), flags , width , precision , 16 , flags .contains ("#" ));
304+ formatInteger (value .getLong (), flags .replace ("+" , "" ).replace (" " , "" ),
305+ width , precision , 8 , flags .contains ("#" ));
306+ case 'x' -> formatInteger (value .getLong (), flags .replace ("+" , "" ).replace (" " , "" ),
307+ width , precision , 16 , flags .contains ("#" ));
301308 case 'X' -> {
302- String result = formatInteger (value .getLong (), flags .replace ("X" , "x" ), width , precision , 16 , flags .contains ("#" ));
309+ String result = formatInteger (value .getLong (), flags .replace ("X" , "x" ).replace ("+" , "" ).replace (" " , "" ),
310+ width , precision , 16 , flags .contains ("#" ));
303311 // Convert to uppercase
304312 yield result .toUpperCase ();
305- // Convert to uppercase
306313 }
307- case 'b' , 'B' -> formatBinary (value .getLong (), flags , width , precision );
314+ case 'b' , 'B' -> formatBinary (value .getLong (), flags , width , precision , conversion );
308315 case 'e' , 'E' , 'g' , 'G' , 'a' , 'A' ->
309316 formatFloatingPoint (value .getDouble (), flags , width , precision , conversion );
310317 case 'f' , 'F' -> // F is synonym for f
@@ -471,7 +478,7 @@ private static String formatUnsigned(RuntimeScalar value, String flags, int widt
471478 return result ;
472479 }
473480
474- private static String formatBinary (long value , String flags , int width , int precision ) {
481+ private static String formatBinary (long value , String flags , int width , int precision , char conversion ) {
475482 String result ;
476483 boolean negative = value < 0 ;
477484
@@ -487,7 +494,7 @@ private static String formatBinary(long value, String flags, int width, int prec
487494 if (precision >= 0 ) {
488495 if (precision == 0 && value == 0 ) {
489496 result = "" ;
490- // But # flag still shows prefix
497+ // But # flag still shows "0" (not prefix)
491498 if (flags .contains ("#" )) {
492499 result = "0" ;
493500 }
@@ -498,7 +505,7 @@ private static String formatBinary(long value, String flags, int width, int prec
498505
499506 // Add prefix if needed
500507 if (flags .contains ("#" ) && value != 0 && !result .isEmpty ()) {
501- String prefix = (flags . contains ( "B" ) || Character . toUpperCase ( flags . charAt ( flags . length () - 1 )) == 'B' ) ? "0B" : "0b" ;
508+ String prefix = (conversion == 'B' ) ? "0B" : "0b" ;
502509 result = prefix + result ;
503510 }
504511
@@ -670,4 +677,4 @@ private static String applyZeroPaddingBinary(String str, int width) {
670677 return prefix + "0" .repeat (Math .max (0 , padLength )) +
671678 number ;
672679 }
673- }
680+ }
0 commit comments