Skip to content

Commit 1e9b470

Browse files
authored
Fix some formatting issues (#1164)
1 parent ee070ad commit 1e9b470

2 files changed

Lines changed: 50 additions & 98 deletions

File tree

Src/IronPython/Runtime/StringFormatter.cs

Lines changed: 45 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -775,39 +775,15 @@ private static string GetAltFormPrefixForRadix(char format, int radix) {
775775

776776
/// <summary>
777777
/// AppendBase appends an integer at the specified radix doing all the
778-
/// special forms for Python. We have a copy and paste version of this
779-
/// for BigInteger below that should be kept in sync.
778+
/// special forms for Python.
780779
/// </summary>
781780
private void AppendBase(char format, int radix) {
782-
bool fPos;
783-
object intVal = GetIntegerValue(out fPos);
784-
if (intVal is BigInteger) {
785-
AppendBaseBigInt((BigInteger)intVal, format, radix);
786-
return;
787-
}
788-
int origVal = (int)intVal;
789-
int val = origVal;
790-
if (val < 0) {
791-
val *= -1;
781+
var str = ProcessNumber(format, radix, ref _opts, GetIntegerValue(out bool fPos));
792782

783+
if (!fPos) {
793784
// if negative number, the leading space has no impact
794785
_opts.Space = false;
795786
}
796-
// we build up the number backwards inside a string builder,
797-
// and after we've finished building this up we append the
798-
// string to our output buffer backwards.
799-
800-
// convert value to string
801-
StringBuilder str = new StringBuilder();
802-
if (val == 0) str.Append('0');
803-
while (val != 0) {
804-
int digit = val % radix;
805-
if (digit < 10) str.Append((char)((digit) + '0'));
806-
else if (char.IsLower(format)) str.Append((char)((digit - 10) + 'a'));
807-
else str.Append((char)((digit - 10) + 'A'));
808-
809-
val /= radix;
810-
}
811787

812788
// pad out for additional precision
813789
if (str.Length < _opts.Precision) {
@@ -817,7 +793,7 @@ private void AppendBase(char format, int radix) {
817793

818794
// pad result to minimum field width
819795
if (_opts.FieldWidth != 0) {
820-
int signLen = (origVal < 0 || _opts.SignChar) ? 1 : 0;
796+
int signLen = (!fPos || _opts.SignChar) ? 1 : 0;
821797
int spaceLen = _opts.Space ? 1 : 0;
822798
int len = _opts.FieldWidth - (str.Length + signLen + spaceLen);
823799

@@ -848,7 +824,7 @@ private void AppendBase(char format, int radix) {
848824

849825

850826
// add any sign if necessary
851-
if (origVal < 0) {
827+
if (!fPos) {
852828
_buf.Append('-');
853829
} else if (_opts.SignChar) {
854830
_buf.Append('+');
@@ -860,83 +836,54 @@ private void AppendBase(char format, int radix) {
860836
for (int i = str.Length - 1; i >= 0; i--) {
861837
_buf.Append(str[i]);
862838
}
863-
}
864839

865-
/// <summary>
866-
/// BigInteger version of AppendBase. Should be kept in sync w/ AppendBase
867-
/// </summary>
868-
private void AppendBaseBigInt(BigInteger origVal, char format, int radix) {
869-
BigInteger val = origVal;
870-
if (val < 0) val *= -1;
871-
872-
// convert value to octal
873-
874-
StringBuilder str = new StringBuilder();
875-
// use .NETs faster conversion if we can
876-
if (radix == 16) {
877-
AppendNumberReversed(str, char.IsLower(format) ? val.ToString("x") : val.ToString("X"));
878-
} else if (radix == 10) {
879-
AppendNumberReversed(str, val.ToString());
880-
} else {
881-
if (val == 0) str.Append('0');
882-
while (val != 0) {
883-
int digit = (int)(val % radix);
884-
if (digit < 10) str.Append((char)((digit) + '0'));
885-
else if (char.IsLower(format)) str.Append((char)((digit - 10) + 'a'));
886-
else str.Append((char)((digit - 10) + 'A'));
887-
888-
val /= radix;
889-
}
890-
}
840+
static StringBuilder ProcessNumber(char format, int radix, ref FormatSettings _opts, object intVal) {
841+
StringBuilder str;
891842

892-
// pad out for additional precision
893-
if (str.Length < _opts.Precision) {
894-
int len = _opts.Precision - str.Length;
895-
str.Append('0', len);
896-
}
843+
// we build up the number backwards inside a string builder,
844+
// and after we've finished building this up we append the
845+
// string to our output buffer backwards.
897846

898-
// pad result to minimum field width
899-
if (_opts.FieldWidth != 0) {
900-
int signLen = (origVal < 0 || _opts.SignChar) ? 1 : 0;
901-
int len = _opts.FieldWidth - (str.Length + signLen);
902-
if (len > 0) {
903-
// we account for the size of the alternate form, if we'll end up adding it.
904-
if (_opts.AltForm && NeedsAltForm(format, (!_opts.LeftAdj && _opts.ZeroPad) ? '0' : str[str.Length - 1])) {
905-
len -= GetAltFormPrefixForRadix(format, radix).Length;
906-
}
847+
if (intVal is BigInteger bi) {
848+
BigInteger val = bi;
849+
if (val < 0) val *= -1;
907850

908-
if (len > 0) {
909-
// and finally append the right form
910-
if (_opts.LeftAdj) {
911-
str.Insert(0, " ", len);
912-
} else {
913-
if (_opts.ZeroPad) {
914-
str.Append('0', len);
915-
} else {
916-
_buf.Append(' ', len);
917-
}
851+
str = new StringBuilder();
852+
853+
// use .NETs faster conversion if we can
854+
if (radix == 16) {
855+
AppendNumberReversed(str, char.IsLower(format) ? val.ToString("x") : val.ToString("X"));
856+
} else if (radix == 10) {
857+
AppendNumberReversed(str, val.ToString());
858+
} else {
859+
if (val == 0) str.Append('0');
860+
while (val != 0) {
861+
int digit = (int)(val % radix);
862+
if (digit < 10) str.Append((char)((digit) + '0'));
863+
else if (char.IsLower(format)) str.Append((char)((digit - 10) + 'a'));
864+
else str.Append((char)((digit - 10) + 'A'));
865+
866+
val /= radix;
918867
}
919868
}
869+
} else {
870+
int val = (int)intVal;
871+
if (val == int.MinValue) return ProcessNumber(format, radix, ref _opts, (BigInteger)val);
872+
if (val < 0) val *= -1;
873+
874+
str = new StringBuilder();
875+
876+
if (val == 0) str.Append('0');
877+
while (val != 0) {
878+
int digit = val % radix;
879+
if (digit < 10) str.Append((char)((digit) + '0'));
880+
else if (char.IsLower(format)) str.Append((char)((digit - 10) + 'a'));
881+
else str.Append((char)((digit - 10) + 'A'));
882+
val /= radix;
883+
}
920884
}
921-
}
922-
923-
// append the alternate form
924-
if (_opts.AltForm && NeedsAltForm(format, str[str.Length - 1]))
925-
str.Append(GetAltFormPrefixForRadix(format, radix));
926-
927885

928-
// add any sign if necessary
929-
if (origVal < 0) {
930-
_buf.Append('-');
931-
} else if (_opts.SignChar) {
932-
_buf.Append('+');
933-
} else if (_opts.Space) {
934-
_buf.Append(' ');
935-
}
936-
937-
// append the final value
938-
for (int i = str.Length - 1; i >= 0; i--) {
939-
_buf.Append(str[i]);
886+
return str;
940887
}
941888
}
942889

Tests/test_formatting.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,11 @@ def test_single(self):
146146
self.assertEqual(str(f), "1.23457e+06")
147147
self.assertEqual("%g" % f, "1.23457e+06")
148148

149+
def test_long(self):
150+
# these were not working properly
151+
self.assertEqual("%x" % (-1 << 31), '-80000000')
152+
self.assertEqual("% 9x" % (1 << 31), ' 80000000')
153+
149154
def test_errors(self):
150155
def formatError():
151156
"%d" % (1,2)

0 commit comments

Comments
 (0)