Skip to content

Commit

Permalink
Showing 3 changed files with 37 additions and 17 deletions.
5 changes: 0 additions & 5 deletions spec/truffle/tags/core/kernel/sprintf_tags.txt
Original file line number Diff line number Diff line change
@@ -8,9 +8,4 @@ fails:Kernel#sprintf passes some tests for negative %f
fails:Kernel#sprintf passes kstephens's tests
fails:Kernel#sprintf returns a String in the same encoding as the format String if compatible
fails:Kernel#sprintf returns a String in the argument encoding if format encoding is more restrictive
fails:Kernel#sprintf with format string that contains %{} sections substitutes values for named references
fails:Kernel#sprintf with format string that contains %{} sections raises KeyError when no matching key is in second argument
fails:Kernel#sprintf with format string that contains %<> sections formats values for named references
fails:Kernel#sprintf with format string that contains %<> sections raises KeyError when no matching key is in second argument
fails:Kernel#sprintf with negative values with format %x precedes the number with '..'
fails:Kernel#sprintf with negative values with format %b or %B precedes the number with '..'
Original file line number Diff line number Diff line change
@@ -17,6 +17,7 @@
import org.jruby.truffle.Layouts;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.core.format.FormatNode;
import org.jruby.truffle.core.format.printf.PrintfTreeBuilder;

import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
@@ -39,31 +40,53 @@ public FormatIntegerBinaryNode(RubyContext context, char format) {
public byte[] format(int spacePadding,
int zeroPadding,
int value) {
return getFormattedString(Integer.toBinaryString(value), spacePadding, zeroPadding, value < 0);
final boolean isSpacePadded = spacePadding != PrintfTreeBuilder.DEFAULT;
final boolean isNegative = value < 0;
final boolean negativeAndSpacePadded = isNegative && isSpacePadded;
final String formatted = negativeAndSpacePadded ? Integer.toBinaryString(-value) : Integer.toBinaryString(value);
return getFormattedString(formatted, spacePadding, zeroPadding, isNegative, isSpacePadded);
}

@TruffleBoundary
@Specialization(guards = "isRubyBignum(value)")
public byte[] format(int spacePadding, int zeroPadding, DynamicObject value) {
final boolean isSpacePadded = spacePadding != PrintfTreeBuilder.DEFAULT;
final BigInteger bigInteger = Layouts.BIGNUM.getValue(value);
return getFormattedString(bigInteger.toString(2), spacePadding, zeroPadding, bigInteger.signum() == -1);
final boolean isNegative = bigInteger.signum() == -1;
final boolean negativeAndSpacePadded = isNegative && isSpacePadded;
final String formatted = negativeAndSpacePadded ? bigInteger.abs().toString(2) : bigInteger.toString(2);
return getFormattedString(formatted, spacePadding, zeroPadding, isNegative, isSpacePadded);
}

@TruffleBoundary
private static byte[] getFormattedString(String formatted, int spacePadding, int zeroPadding, boolean negative) {
if (negative) {
if(formatted.contains("0")){
formatted = "..1" + formatted.substring(formatted.indexOf('0'), formatted.length());
private static byte[] getFormattedString(String formatted, int spacePadding, int zeroPadding, boolean isNegative, boolean isSpacePadded) {
if (isNegative && !isSpacePadded) {
if (formatted.contains("0")) {
formatted = formatted.substring(formatted.indexOf('0'), formatted.length());
if (formatted.length() + 3 < zeroPadding) {
final int addOnes = zeroPadding - (formatted.length() + 3);
for (int i = addOnes; i > 0; i--) {
formatted = "1" + formatted;
}
}
formatted = "..1" + formatted;
} else {
formatted = "..1";
}
} else {
while (formatted.length() < zeroPadding) {
formatted = "0" + formatted;
}
}
while (formatted.length() < spacePadding) {
formatted = " " + formatted;
}
while (formatted.length() < zeroPadding) {
formatted = "0" + formatted;

if (isSpacePadded) {
if (isNegative) {
formatted = "-" + formatted;
} else {
formatted = " " + formatted;
}
}

return formatted.getBytes(StandardCharsets.US_ASCII);
}

Original file line number Diff line number Diff line change
@@ -95,8 +95,10 @@ public void exitFormat(PrintfParser.FormatContext ctx) {
} else if (flag.SPACE() != null) {
if (n + 1 < ctx.flag().size() && ctx.flag(n + 1).STAR() != null) {
spacePadding = PADDING_FROM_ARGUMENT;
} else {
} else if(width != DEFAULT) {
spacePadding = width;
} else {
spacePadding = 1;
}
} else if (flag.ZERO() != null) {
if (n + 1 < ctx.flag().size() && ctx.flag(n + 1).STAR() != null) {

0 comments on commit 3f648c0

Please sign in to comment.