Skip to content

Commit

Permalink
Showing 3 changed files with 23 additions and 14 deletions.
1 change: 0 additions & 1 deletion spec/truffle/tags/core/string/modulo_tags.txt
Original file line number Diff line number Diff line change
@@ -53,7 +53,6 @@ fails:String#% supports string formats using %s
fails:String#% taints result for %s when argument is tainted
fails:String#% raises an ArgumentError for huge precisions for %s
fails:String#% supports unsigned formats using %u
fails:String#% formats negative values with a leading sign using %u
fails:String#% supports hex formats using %x for positive numbers
fails:String#% supports hex formats using %x for negative numbers
fails:String#% supports hex formats using %X for positive numbers
Original file line number Diff line number Diff line change
@@ -30,10 +30,12 @@
public abstract class FormatIntegerBinaryNode extends FormatNode {

private final char format;
private final boolean hasPlusFlag;

public FormatIntegerBinaryNode(RubyContext context, char format) {
public FormatIntegerBinaryNode(RubyContext context, char format, boolean hasPlusFlag) {
super(context);
this.format = format;
this.hasPlusFlag = hasPlusFlag;
}

@Specialization
@@ -42,9 +44,9 @@ public byte[] format(int spacePadding,
int value) {
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);
final boolean negativeAndPadded = isNegative && (isSpacePadded || this.hasPlusFlag);
final String formatted = negativeAndPadded ? Integer.toBinaryString(-value) : Integer.toBinaryString(value);
return getFormattedString(formatted, spacePadding, zeroPadding, isNegative, isSpacePadded, this.hasPlusFlag);
}

@TruffleBoundary
@@ -53,14 +55,15 @@ public byte[] format(int spacePadding, int zeroPadding, DynamicObject value) {
final boolean isSpacePadded = spacePadding != PrintfTreeBuilder.DEFAULT;
final BigInteger bigInteger = Layouts.BIGNUM.getValue(value);
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);
final boolean negativeAndPadded = isNegative && (isSpacePadded || this.hasPlusFlag);
final String formatted = negativeAndPadded ? bigInteger.abs().toString(2) : bigInteger.toString(2);
return getFormattedString(formatted, spacePadding, zeroPadding, isNegative, isSpacePadded, this.hasPlusFlag);
}

@TruffleBoundary
private static byte[] getFormattedString(String formatted, int spacePadding, int zeroPadding, boolean isNegative, boolean isSpacePadded) {
if (isNegative && !isSpacePadded) {
private static byte[] getFormattedString(String formatted, int spacePadding, int zeroPadding, boolean isNegative,
boolean isSpacePadded, boolean hasPlusFlag) {
if (isNegative && !(isSpacePadded || hasPlusFlag)) {
if (formatted.contains("0")) {
formatted = formatted.substring(formatted.indexOf('0'), formatted.length());
if (formatted.length() + 3 < zeroPadding) {
@@ -79,11 +82,16 @@ private static byte[] getFormattedString(String formatted, int spacePadding, int
}
}

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

}
}

Original file line number Diff line number Diff line change
@@ -85,7 +85,7 @@ public void exitFormat(PrintfParser.FormatContext ctx) {
boolean leftJustified = false;
int spacePadding = DEFAULT;
int zeroPadding = DEFAULT;

boolean hasPlusFlag = false;

for (int n = 0; n < ctx.flag().size(); n++) {
final PrintfParser.FlagContext flag = ctx.flag(n);
@@ -108,6 +108,8 @@ public void exitFormat(PrintfParser.FormatContext ctx) {
}
} else if (flag.STAR() != null) {
// Handled in space and zero, above
} else if (flag.PLUS() != null) {
hasPlusFlag = true;
} else {
throw new UnsupportedOperationException();
}
@@ -214,7 +216,7 @@ public void exitFormat(PrintfParser.FormatContext ctx) {

if(type == 'b' || type == 'B'){
node = WriteBytesNodeGen.create(context,
FormatIntegerBinaryNodeGen.create(context, format,
FormatIntegerBinaryNodeGen.create(context, format, hasPlusFlag,
spacePaddingNode,
zeroPaddingNode,
ToIntegerNodeGen.create(context, valueNode)));

0 comments on commit 96bbce1

Please sign in to comment.