diff --git a/src/main/java/org/luaj/vm3/lib/StringLib.java b/src/main/java/org/luaj/vm3/lib/StringLib.java index 4f0f1b7d1..e19db9411 100644 --- a/src/main/java/org/luaj/vm3/lib/StringLib.java +++ b/src/main/java/org/luaj/vm3/lib/StringLib.java @@ -357,6 +357,7 @@ public class StringLib extends TwoArgFunction { private DecimalFormat floatingFormat; public FormatDesc(Varargs args, LuaString strfrmt, final int start) { + // TODO: force positive sign scientificFormat = new DecimalFormat("0.000000E00"); floatingFormat = new DecimalFormat("0.000000"); int p = start, n = strfrmt.length(); @@ -373,7 +374,7 @@ public class StringLib extends TwoArgFunction { default: moreFlags = false; break; } } - if ( p - start > MAX_FLAGS ) + if ( p - start - 1 > MAX_FLAGS ) error("invalid format (repeated flags)"); width = -1; @@ -408,8 +409,13 @@ public class StringLib extends TwoArgFunction { } public void format(Buffer buf, byte c) { - // TODO: not clear that any of width, precision, or flags apply here. + if ( !leftAdjust ) + pad( buf, ' ', width - 1 ); + buf.append(c); + + if ( leftAdjust ) + pad( buf, ' ', width - 1 ); } public void format(Buffer buf, long number) { @@ -440,6 +446,99 @@ public class StringLib extends TwoArgFunction { int ndigits = minwidth; int nzeros; + boolean allowPlusSpace = conversion == 'd' || conversion == 'i'; + + if ( number < 0 ) { + ndigits--; + } else if ( allowPlusSpace && (explicitPlus || space) ) { + minwidth++; + } + + if ( alternateForm ) { + switch ( conversion ) { + case 'o': + minwidth++; + break; + case 'x': + case 'X': + minwidth+=2; + break; + } + } + + if ( precision > ndigits ) + nzeros = precision - ndigits; + else if ( precision == -1 && zeroPad && width > minwidth ) + nzeros = width - minwidth; + else + nzeros = 0; + + minwidth += nzeros; + int nspaces = width > minwidth ? width - minwidth : 0; + + if ( !leftAdjust ) + pad( buf, ' ', nspaces ); + + if ( number < 0 ) { + if ( nzeros > 0 ) { + buf.append( (byte)'-' ); + digits = digits.substring( 1 ); + } + } else if ( allowPlusSpace && explicitPlus ) { + buf.append( (byte)'+' ); + } else if ( allowPlusSpace && space ) { + buf.append( (byte)' ' ); + } + + if ( alternateForm ) { + switch ( conversion ) { + case 'o': + buf.append( (byte)'0' ); + break; + case 'x': + buf.append( "0x" ); + break; + case 'X': + buf.append( "0X" ); + break; + } + } + + if ( nzeros > 0 ) + pad( buf, '0', nzeros ); + + buf.append( digits ); + + if ( leftAdjust ) + pad( buf, ' ', nspaces ); + } + + public void format(Buffer buf, double number) { + // TODO: precision, alternateForm + String digits; + + switch ( conversion ) { + case 'e': + digits = scientificFormat.format( number ).toLowerCase(); + break; + case 'E': + digits = scientificFormat.format( number ); + break; + case 'f': + digits = floatingFormat.format(number); + break; + case 'g': + case 'G': + default: + //TODO: g, G + digits = String.valueOf( number ); + break; + } + + int minwidth = digits.length(); + int ndigits = minwidth; + int nzeros; + if ( number < 0 ) { ndigits--; } else if ( explicitPlus || space ) { @@ -479,26 +578,6 @@ public class StringLib extends TwoArgFunction { pad( buf, ' ', nspaces ); } - public void format(Buffer buf, double x) { - switch ( conversion ) { - case 'e': - buf.append( scientificFormat.format( x ).toLowerCase() ); - break; - case 'E': - buf.append( scientificFormat.format( x ) ); - break; - case 'f': - buf.append( floatingFormat.format(x) ); - break; - case 'g': - case 'G': - default: - //TODO: g, G - buf.append( String.valueOf( x ) ); - break; - } - } - public void format(Buffer buf, LuaString s) { int nullindex = s.indexOf( (byte)'\0', 0 ); if ( nullindex != -1 )