while (true) {
std::optional<int> repeat;
bool unlimited{false};
+ auto maybeReversionPoint{offset_};
CharType ch{GetNextChar(context)};
while (ch == ',' || ch == ':') {
// Skip commas, and don't complain if they're missing; the format
return 0;
}
stack_[height_].start = offset_ - 1; // the '('
+ RUNTIME_CHECK(context, format_[stack_[height_].start] == '(');
if (unlimited || height_ == 0) {
stack_[height_].remaining = Iteration::unlimited;
unlimitedLoopCheck = offset_ - 1;
} else {
stack_[height_].remaining = 0;
}
+ if (height_ == 1) {
+ // Subtle point (F'2018 13.4 para 9): tha last parenthesized group
+ // at height 1 becomes the restart point after control reaches the
+ // end of the format, including its repeat count.
+ stack_[0].start = maybeReversionPoint - 1;
+ }
++height_;
} else if (height_ == 0) {
context.SignalError(IostatErrorInFormat, "FORMAT lacks initial '('");
}
context.AdvanceRecord(); // implied / before rightmost )
}
+ auto restart{stack_[height_ - 1].start + 1};
if (stack_[height_ - 1].remaining == Iteration::unlimited) {
- offset_ = stack_[height_ - 1].start + 1;
+ offset_ = restart;
if (offset_ == unlimitedLoopCheck) {
context.SignalError(IostatErrorInFormat,
"Unlimited repetition in FORMAT lacks data edit descriptors");
}
} else if (stack_[height_ - 1].remaining-- > 0) {
- offset_ = stack_[height_ - 1].start + 1;
+ offset_ = restart;
} else {
--height_;
}
++height_;
}
edit.repeat = 1;
- if (height_ > 1) {
+ if (height_ > 1) { // Subtle: stack_[0].start doesn't necessarily point to '('
int start{stack_[height_ - 1].start};
if (format_[start] != '(') {
if (stack_[height_ - 1].remaining > maxRepeat) {
}
static void multiline() {
- char buffer[4][32];
+ char buffer[5][32];
StaticDescriptor<1> staticDescriptor[2];
Descriptor &whole{staticDescriptor[0].descriptor()};
- SubscriptValue extent[]{4};
+ SubscriptValue extent[]{5};
whole.Establish(TypeCode{CFI_type_char}, sizeof buffer[0], &buffer, 1, extent,
CFI_attribute_pointer);
whole.Dump();
whole.Check();
Descriptor §ion{staticDescriptor[1].descriptor()};
- SubscriptValue lowers[]{0}, uppers[]{3}, strides[]{1};
+ SubscriptValue lowers[]{0}, uppers[]{4}, strides[]{1};
section.Establish(whole.type(), whole.ElementBytes(), nullptr, 1, extent,
CFI_attribute_pointer);
if (auto error{
}
section.Dump();
section.Check();
- const char *format{"('?abcde,',T1,'>',T9,A,TL12,A,TR25,'<'//G0,25X,'done')"};
+ const char *format{
+ "('?abcde,',T1,'>',T9,A,TL12,A,TR25,'<'//G0,17X,'abcd',1(2I4))"};
auto cookie{IONAME(BeginInternalArrayFormattedOutput)(
section, format, std::strlen(format))};
IONAME(OutputAscii)(cookie, "WORLD", 5);
IONAME(OutputAscii)(cookie, "HELLO", 5);
IONAME(OutputInteger64)(cookie, 789);
+ for (int j{666}; j <= 999; j += 111) {
+ IONAME(OutputInteger64)(cookie, j);
+ }
if (auto status{IONAME(EndIoStatement)(cookie)}) {
Fail() << "multiline: '" << format << "' failed, status "
<< static_cast<int>(status) << '\n';
test(format,
">HELLO, WORLD <"
" "
- "789 done"
+ "789 abcd 666 777"
+ " 888 999 "
" ",
std::string{buffer[0], sizeof buffer});
}