@@ -17,7 +17,7 @@ namespace Fortran::runtime::io {
1717RT_OFFLOAD_API_GROUP_BEGIN
1818
1919// In output statement, add a space between numbers and characters.
20- static RT_API_ATTRS void addSpaceBeforeCharacter (IoStatementState &io) {
20+ static RT_API_ATTRS void AddSpaceBeforeCharacter (IoStatementState &io) {
2121 if (auto *list{io.get_if <ListDirectedStatementState<Direction::Output>>()}) {
2222 list->set_lastWasUndelimitedCharacter (false );
2323 }
@@ -29,7 +29,7 @@ static RT_API_ATTRS void addSpaceBeforeCharacter(IoStatementState &io) {
2929template <int LOG2_BASE>
3030static RT_API_ATTRS bool EditBOZOutput (IoStatementState &io,
3131 const DataEdit &edit, const unsigned char *data0, std::size_t bytes) {
32- addSpaceBeforeCharacter (io);
32+ AddSpaceBeforeCharacter (io);
3333 int digits{static_cast <int >((bytes * 8 ) / LOG2_BASE)};
3434 int get{static_cast <int >(bytes * 8 ) - digits * LOG2_BASE};
3535 if (get > 0 ) {
@@ -110,27 +110,11 @@ static RT_API_ATTRS bool EditBOZOutput(IoStatementState &io,
110110template <int KIND>
111111bool RT_API_ATTRS EditIntegerOutput (IoStatementState &io, const DataEdit &edit,
112112 common::HostSignedIntType<8 * KIND> n, bool isSigned) {
113- addSpaceBeforeCharacter (io);
114- char buffer[130 ], *end{&buffer[sizeof buffer]}, *p{end};
115- bool isNegative{isSigned && n < 0 };
116- using Unsigned = common::HostUnsignedIntType<8 * KIND>;
117- Unsigned un{static_cast <Unsigned>(n)};
118- int signChars{0 };
113+ AddSpaceBeforeCharacter (io);
119114 switch (edit.descriptor ) {
120115 case DataEdit::ListDirected:
121116 case ' G' :
122117 case ' I' :
123- if (isNegative) {
124- un = -un;
125- }
126- if (isNegative || (edit.modes .editingFlags & signPlus)) {
127- signChars = 1 ; // '-' or '+'
128- }
129- while (un > 0 ) {
130- auto quotient{un / 10u };
131- *--p = ' 0' + static_cast <int >(un - Unsigned{10 } * quotient);
132- un = quotient;
133- }
134118 break ;
135119 case ' B' :
136120 return EditBOZOutput<1 >(
@@ -152,7 +136,22 @@ bool RT_API_ATTRS EditIntegerOutput(IoStatementState &io, const DataEdit &edit,
152136 edit.descriptor );
153137 return false ;
154138 }
155-
139+ char buffer[130 ], *end{&buffer[sizeof buffer]}, *p{end};
140+ bool isNegative{isSigned && n < 0 };
141+ using Unsigned = common::HostUnsignedIntType<8 * KIND>;
142+ Unsigned un{static_cast <Unsigned>(n)};
143+ int signChars{0 };
144+ if (isNegative) {
145+ un = -un;
146+ }
147+ if (isNegative || (edit.modes .editingFlags & signPlus)) {
148+ signChars = 1 ; // '-' or '+'
149+ }
150+ while (un > 0 ) {
151+ auto quotient{un / 10u };
152+ *--p = ' 0' + static_cast <int >(un - Unsigned{10 } * quotient);
153+ un = quotient;
154+ }
156155 int digits = end - p;
157156 int leadingZeroes{0 };
158157 int editWidth{edit.width .value_or (0 )};
@@ -181,6 +180,10 @@ bool RT_API_ATTRS EditIntegerOutput(IoStatementState &io, const DataEdit &edit,
181180 return false ;
182181 }
183182 leadingSpaces = 1 ;
183+ } else if (!edit.width ) {
184+ // Bare 'I' and 'G' are interpreted with various default widths in the
185+ // compilers that support them, so there's always some leading space.
186+ leadingSpaces = std::max (1 , leadingSpaces);
184187 }
185188 return EmitRepeated (io, ' ' , leadingSpaces) &&
186189 EmitAscii (io, n < 0 ? " -" : " +" , signChars) &&
@@ -291,7 +294,7 @@ static RT_API_ATTRS bool IsInfOrNaN(const char *p, int length) {
291294template <int KIND>
292295RT_API_ATTRS bool RealOutputEditing<KIND>::EditEorDOutput(
293296 const DataEdit &edit) {
294- addSpaceBeforeCharacter (io_);
297+ AddSpaceBeforeCharacter (io_);
295298 int editDigits{edit.digits .value_or (0 )}; // 'd' field
296299 int editWidth{edit.width .value_or (0 )}; // 'w' field
297300 int significantDigits{editDigits};
@@ -427,7 +430,7 @@ RT_API_ATTRS bool RealOutputEditing<KIND>::EditEorDOutput(
427430// 13.7.2.3.2 in F'2018
428431template <int KIND>
429432RT_API_ATTRS bool RealOutputEditing<KIND>::EditFOutput(const DataEdit &edit) {
430- addSpaceBeforeCharacter (io_);
433+ AddSpaceBeforeCharacter (io_);
431434 int fracDigits{edit.digits .value_or (0 )}; // 'd' field
432435 const int editWidth{edit.width .value_or (0 )}; // 'w' field
433436 enum decimal::FortranRounding rounding{edit.modes .round };
@@ -702,7 +705,7 @@ RT_API_ATTRS auto RealOutputEditing<KIND>::ConvertToHexadecimal(
702705
703706template <int KIND>
704707RT_API_ATTRS bool RealOutputEditing<KIND>::EditEXOutput(const DataEdit &edit) {
705- addSpaceBeforeCharacter (io_);
708+ AddSpaceBeforeCharacter (io_);
706709 int editDigits{edit.digits .value_or (0 )}; // 'd' field
707710 int significantDigits{editDigits + 1 };
708711 int flags{0 };
0 commit comments