forked from OSchip/llvm-project
[flang][runtime] Don't emit any leading blanks for G0/E0 output editing
There were cases where E0.d output editing (or G0.d editing that is converted to E0.d) would emit one or more leading blank characters; fix them. Differential Revision: https://reviews.llvm.org/D127426
This commit is contained in:
parent
17457be1c3
commit
3f3edbe5fc
|
@ -258,6 +258,7 @@ bool RealOutputEditing<binaryPrecision>::EditEorDOutput(const DataEdit &edit) {
|
|||
if (edit.modes.editingFlags & signPlus) {
|
||||
flags |= decimal::AlwaysSign;
|
||||
}
|
||||
bool noLeadingSpaces{editWidth == 0};
|
||||
if (editWidth == 0) { // "the processor selects the field width"
|
||||
if (edit.digits.has_value()) { // E0.d
|
||||
if (editDigits == 0) { // E0.0
|
||||
|
@ -360,6 +361,9 @@ bool RealOutputEditing<binaryPrecision>::EditEorDOutput(const DataEdit &edit) {
|
|||
zeroesBeforePoint = 1;
|
||||
++totalLength;
|
||||
}
|
||||
if (totalLength < width && noLeadingSpaces) {
|
||||
width = totalLength;
|
||||
}
|
||||
return EmitPrefix(edit, totalLength, width) &&
|
||||
io_.Emit(converted.str, signLength + digitsBeforePoint) &&
|
||||
io_.EmitRepeated('0', zeroesBeforePoint) &&
|
||||
|
@ -475,9 +479,10 @@ bool RealOutputEditing<binaryPrecision>::EditFOutput(const DataEdit &edit) {
|
|||
template <int binaryPrecision>
|
||||
DataEdit RealOutputEditing<binaryPrecision>::EditForGOutput(DataEdit edit) {
|
||||
edit.descriptor = 'E';
|
||||
int editWidth{edit.width.value_or(0)};
|
||||
int significantDigits{
|
||||
edit.digits.value_or(BinaryFloatingPoint::decimalPrecision)}; // 'd'
|
||||
if (!edit.width.has_value() || (*edit.width > 0 && significantDigits == 0)) {
|
||||
if (editWidth > 0 && significantDigits == 0) {
|
||||
return edit; // Gw.0 -> Ew.0 for w > 0
|
||||
}
|
||||
int flags{0};
|
||||
|
@ -487,7 +492,7 @@ DataEdit RealOutputEditing<binaryPrecision>::EditForGOutput(DataEdit edit) {
|
|||
decimal::ConversionToDecimalResult converted{
|
||||
Convert(significantDigits, edit.modes.round, flags)};
|
||||
if (IsInfOrNaN(converted)) {
|
||||
return edit;
|
||||
return edit; // Inf/Nan -> Ew.d (same as Fw.d)
|
||||
}
|
||||
int expo{IsZero() ? 1 : converted.decimalExponent}; // 's'
|
||||
if (expo < 0 || expo > significantDigits) {
|
||||
|
@ -496,7 +501,6 @@ DataEdit RealOutputEditing<binaryPrecision>::EditForGOutput(DataEdit edit) {
|
|||
edit.descriptor = 'F';
|
||||
edit.modes.scale = 0; // kP is ignored for G when no exponent field
|
||||
trailingBlanks_ = 0;
|
||||
int editWidth{edit.width.value_or(0)};
|
||||
if (editWidth > 0) {
|
||||
int expoDigits{edit.expoDigits.value_or(0)};
|
||||
trailingBlanks_ = expoDigits > 0 ? expoDigits + 2 : 4; // 'n'
|
||||
|
|
|
@ -280,8 +280,8 @@ TEST(IOApiTests, FormatZeroes) {
|
|||
for (auto const &[format, expect] : zeroes) {
|
||||
std::string got;
|
||||
ASSERT_TRUE(CompareFormatReal(format, 0.0, expect, got))
|
||||
<< "Failed to format " << format << ", expected " << expect << ", got "
|
||||
<< got;
|
||||
<< "Failed to format " << format << ", expected '" << expect
|
||||
<< "', got '" << got << "'";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -311,8 +311,8 @@ TEST(IOApiTests, FormatOnes) {
|
|||
for (auto const &[format, expect] : ones) {
|
||||
std::string got;
|
||||
ASSERT_TRUE(CompareFormatReal(format, 1.0, expect, got))
|
||||
<< "Failed to format " << format << ", expected " << expect << ", got "
|
||||
<< got;
|
||||
<< "Failed to format " << format << ", expected '" << expect
|
||||
<< "', got '" << got << "'";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -326,8 +326,8 @@ TEST(IOApiTests, FormatNegativeOnes) {
|
|||
for (auto const &[format, expect] : negOnes) {
|
||||
std::string got;
|
||||
ASSERT_TRUE(CompareFormatReal(format, -1.0, expect, got))
|
||||
<< "Failed to format " << format << ", expected " << expect << ", got "
|
||||
<< got;
|
||||
<< "Failed to format " << format << ", expected '" << expect
|
||||
<< "', got '" << got << "'";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -394,7 +394,7 @@ TEST(IOApiTests, FormatDoubleValues) {
|
|||
{"(E62.55,';')",
|
||||
" 0.1000000000000000055511151231257827021181583404541015625E+"
|
||||
"00;"},
|
||||
{"(E0.0,';')", " 0.E+00;"},
|
||||
{"(E0.0,';')", "0.E+00;"},
|
||||
{"(E0.55,';')",
|
||||
"0.1000000000000000055511151231257827021181583404541015625E+"
|
||||
"00;"},
|
||||
|
@ -624,8 +624,8 @@ TEST(IOApiTests, FormatDoubleValues) {
|
|||
for (auto const &[format, expect] : cases) {
|
||||
std::string got;
|
||||
ASSERT_TRUE(CompareFormatReal(format, value, expect, got))
|
||||
<< "Failed to format " << format << ", expected " << expect
|
||||
<< ", got " << got;
|
||||
<< "Failed to format " << format << ", expected '" << expect
|
||||
<< "', got '" << got << "'";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -669,8 +669,8 @@ TEST(IOApiTests, FormatDoubleValues) {
|
|||
for (auto const &[format, value, expect] : individualTestCases) {
|
||||
std::string got;
|
||||
ASSERT_TRUE(CompareFormatReal(format, value, expect, got))
|
||||
<< "Failed to format " << format << ", expected " << expect << ", got "
|
||||
<< got;
|
||||
<< "Failed to format " << format << ", expected '" << expect
|
||||
<< "', got '" << got << "'";
|
||||
}
|
||||
|
||||
// Problematic EN formatting edge cases with rounding
|
||||
|
@ -688,7 +688,8 @@ TEST(IOApiTests, FormatDoubleValues) {
|
|||
for (auto const &[value, expect] : individualENTestCases) {
|
||||
std::string got;
|
||||
ASSERT_TRUE(CompareFormatReal("(EN10.1)", value, expect, got))
|
||||
<< "Failed to format EN10.1, expected " << expect << ", got " << got;
|
||||
<< "Failed to format EN10.1, expected '" << expect << "', got '" << got
|
||||
<< "'";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue