@@ -33,59 +33,6 @@ FormatControl<CONTEXT>::FormatControl(const Terminator &terminator,
33
33
stack_[0 ].remaining = Iteration::unlimited; // 13.4(8)
34
34
}
35
35
36
- template <typename CONTEXT>
37
- int FormatControl<CONTEXT>::GetMaxParenthesisNesting(
38
- IoErrorHandler &handler, const CharType *format, std::size_t formatLength) {
39
- int maxNesting{0 };
40
- int nesting{0 };
41
- const CharType *end{format + formatLength};
42
- std::optional<CharType> quote;
43
- int repeat{0 };
44
- for (const CharType *p{format}; p < end; ++p) {
45
- if (quote) {
46
- if (*p == *quote) {
47
- quote.reset ();
48
- }
49
- } else if (*p >= ' 0' && *p <= ' 9' ) {
50
- repeat = 10 * repeat + *p - ' 0' ;
51
- } else if (*p != ' ' ) {
52
- switch (*p) {
53
- case ' \' ' :
54
- case ' "' :
55
- quote = *p;
56
- break ;
57
- case ' h' :
58
- case ' H' : // 9HHOLLERITH
59
- p += repeat;
60
- if (p >= end) {
61
- handler.SignalError (IostatErrorInFormat,
62
- " Hollerith (%dH) too long in FORMAT" , repeat);
63
- return maxNesting;
64
- }
65
- break ;
66
- case ' ' :
67
- break ;
68
- case ' (' :
69
- ++nesting;
70
- maxNesting = std::max (nesting, maxNesting);
71
- break ;
72
- case ' )' :
73
- nesting = std::max (nesting - 1 , 0 );
74
- break ;
75
- }
76
- repeat = 0 ;
77
- }
78
- }
79
- if (quote) {
80
- handler.SignalError (
81
- IostatErrorInFormat, " Unbalanced quotation marks in FORMAT string" );
82
- } else if (nesting) {
83
- handler.SignalError (
84
- IostatErrorInFormat, " Unbalanced parentheses in FORMAT string" );
85
- }
86
- return maxNesting;
87
- }
88
-
89
36
template <typename CONTEXT>
90
37
int FormatControl<CONTEXT>::GetIntField(
91
38
IoErrorHandler &handler, CharType firstCh) {
@@ -98,7 +45,11 @@ int FormatControl<CONTEXT>::GetIntField(
98
45
int result{0 };
99
46
bool negate{ch == ' -' };
100
47
if (negate || ch == ' +' ) {
101
- firstCh = ' \0 ' ;
48
+ if (firstCh) {
49
+ firstCh = ' \0 ' ;
50
+ } else {
51
+ ++offset_;
52
+ }
102
53
ch = PeekNext ();
103
54
}
104
55
while (ch >= ' 0' && ch <= ' 9' ) {
@@ -222,6 +173,15 @@ static void HandleControl(CONTEXT &context, char ch, char next, int n) {
222
173
template <typename CONTEXT>
223
174
int FormatControl<CONTEXT>::CueUpNextDataEdit(Context &context, bool stop) {
224
175
int unlimitedLoopCheck{-1 };
176
+ // Do repetitions remain on an unparenthesized data edit?
177
+ while (height_ > 1 && format_[stack_[height_ - 1 ].start ] != ' (' ) {
178
+ offset_ = stack_[height_ - 1 ].start ;
179
+ int repeat{stack_[height_ - 1 ].remaining };
180
+ --height_;
181
+ if (repeat > 0 ) {
182
+ return repeat;
183
+ }
184
+ }
225
185
while (true ) {
226
186
std::optional<int > repeat;
227
187
bool unlimited{false };
@@ -242,16 +202,18 @@ int FormatControl<CONTEXT>::CueUpNextDataEdit(Context &context, bool stop) {
242
202
unlimited = true ;
243
203
ch = GetNextChar (context);
244
204
if (ch != ' (' ) {
245
- context.SignalError (IostatErrorInFormat,
246
- " Invalid FORMAT: '*' may appear only before '('" );
205
+ ReportBadFormat (context,
206
+ " Invalid FORMAT: '*' may appear only before '('" ,
207
+ maybeReversionPoint);
247
208
return 0 ;
248
209
}
249
210
}
250
211
ch = Capitalize (ch);
251
212
if (ch == ' (' ) {
252
213
if (height_ >= maxHeight_) {
253
- context.SignalError (IostatErrorInFormat,
254
- " FORMAT stack overflow: too many nested parentheses" );
214
+ ReportBadFormat (context,
215
+ " FORMAT stack overflow: too many nested parentheses" ,
216
+ maybeReversionPoint);
255
217
return 0 ;
256
218
}
257
219
stack_[height_].start = offset_ - 1 ; // the '('
@@ -271,11 +233,11 @@ int FormatControl<CONTEXT>::CueUpNextDataEdit(Context &context, bool stop) {
271
233
// Subtle point (F'2018 13.4 para 9): tha last parenthesized group
272
234
// at height 1 becomes the restart point after control reaches the
273
235
// end of the format, including its repeat count.
274
- stack_[0 ].start = maybeReversionPoint - 1 ;
236
+ stack_[0 ].start = maybeReversionPoint;
275
237
}
276
238
++height_;
277
239
} else if (height_ == 0 ) {
278
- context. SignalError (IostatErrorInFormat , " FORMAT lacks initial '('" );
240
+ ReportBadFormat (context , " FORMAT lacks initial '('" , maybeReversionPoint );
279
241
return 0 ;
280
242
} else if (ch == ' )' ) {
281
243
if (height_ == 1 ) {
@@ -284,12 +246,16 @@ int FormatControl<CONTEXT>::CueUpNextDataEdit(Context &context, bool stop) {
284
246
}
285
247
context.AdvanceRecord (); // implied / before rightmost )
286
248
}
287
- auto restart{stack_[height_ - 1 ].start + 1 };
249
+ auto restart{stack_[height_ - 1 ].start };
250
+ if (format_[restart] == ' (' ) {
251
+ ++restart;
252
+ }
288
253
if (stack_[height_ - 1 ].remaining == Iteration::unlimited) {
289
254
offset_ = restart;
290
255
if (offset_ == unlimitedLoopCheck) {
291
- context.SignalError (IostatErrorInFormat,
292
- " Unlimited repetition in FORMAT lacks data edit descriptors" );
256
+ ReportBadFormat (context,
257
+ " Unlimited repetition in FORMAT lacks data edit descriptors" ,
258
+ restart);
293
259
}
294
260
} else if (stack_[height_ - 1 ].remaining -- > 0 ) {
295
261
offset_ = restart;
@@ -304,8 +270,9 @@ int FormatControl<CONTEXT>::CueUpNextDataEdit(Context &context, bool stop) {
304
270
++offset_;
305
271
}
306
272
if (offset_ >= formatLength_) {
307
- context.SignalError (IostatErrorInFormat,
308
- " FORMAT missing closing quote on character literal" );
273
+ ReportBadFormat (context,
274
+ " FORMAT missing closing quote on character literal" ,
275
+ maybeReversionPoint);
309
276
return 0 ;
310
277
}
311
278
++offset_;
@@ -322,8 +289,8 @@ int FormatControl<CONTEXT>::CueUpNextDataEdit(Context &context, bool stop) {
322
289
} else if (ch == ' H' ) {
323
290
// 9HHOLLERITH
324
291
if (!repeat || *repeat < 1 || offset_ + *repeat > formatLength_) {
325
- context. SignalError (
326
- IostatErrorInFormat, " Invalid width on Hollerith in FORMAT " );
292
+ ReportBadFormat (context, " Invalid width on Hollerith in FORMAT " ,
293
+ maybeReversionPoint );
327
294
return 0 ;
328
295
}
329
296
context.Emit (format_ + offset_, static_cast <std::size_t >(*repeat));
@@ -364,8 +331,8 @@ int FormatControl<CONTEXT>::CueUpNextDataEdit(Context &context, bool stop) {
364
331
// TODO: any other raw characters?
365
332
context.Emit (format_ + offset_ - 1 , 1 );
366
333
} else {
367
- context. SignalError (IostatErrorInFormat,
368
- " Invalid character '%c' in FORMAT" , static_cast < char >(ch) );
334
+ ReportBadFormat (
335
+ context, " Invalid character in FORMAT" , maybeReversionPoint );
369
336
return 0 ;
370
337
}
371
338
}
@@ -410,11 +377,9 @@ DataEdit FormatControl<CONTEXT>::GetNextDataEdit(
410
377
}
411
378
}
412
379
if (!ok) {
413
- context.SignalError (
414
- IostatErrorInFormat, " Unclosed DT'iotype' in FORMAT" );
380
+ ReportBadFormat (context, " Unclosed DT'iotype' in FORMAT" , start);
415
381
} else if (tooLong) {
416
- context.SignalError (
417
- IostatErrorInFormat, " Excessive DT'iotype' in FORMAT" );
382
+ ReportBadFormat (context, " Excessive DT'iotype' in FORMAT" , start);
418
383
}
419
384
}
420
385
if (PeekNext () == ' (' ) {
@@ -434,11 +399,9 @@ DataEdit FormatControl<CONTEXT>::GetNextDataEdit(
434
399
}
435
400
}
436
401
if (!ok) {
437
- context.SignalError (
438
- IostatErrorInFormat, " Unclosed DT(v_list) in FORMAT" );
402
+ ReportBadFormat (context, " Unclosed DT(v_list) in FORMAT" , start);
439
403
} else if (tooLong) {
440
- context.SignalError (
441
- IostatErrorInFormat, " Excessive DT(v_list) in FORMAT" );
404
+ ReportBadFormat (context, " Excessive DT(v_list) in FORMAT" , start);
442
405
}
443
406
}
444
407
}
@@ -460,27 +423,13 @@ DataEdit FormatControl<CONTEXT>::GetNextDataEdit(
460
423
}
461
424
}
462
425
edit.modes = context.mutableModes ();
463
-
464
426
// Handle repeated nonparenthesized edit descriptors
427
+ edit.repeat = std::min (repeat, maxRepeat); // 0 if maxRepeat==0
465
428
if (repeat > maxRepeat) {
466
429
stack_[height_].start = start; // after repeat count
467
- stack_[height_].remaining = repeat; // full count
430
+ stack_[height_].remaining = repeat - edit. repeat ;
468
431
++height_;
469
432
}
470
- edit.repeat = std::min (1 , maxRepeat); // 0 if maxRepeat==0
471
- if (height_ > 1 ) { // Subtle: stack_[0].start doesn't necessarily point to '('
472
- int start{stack_[height_ - 1 ].start };
473
- if (format_[start] != ' (' ) {
474
- if (stack_[height_ - 1 ].remaining > maxRepeat) {
475
- edit.repeat = maxRepeat;
476
- stack_[height_ - 1 ].remaining -= maxRepeat;
477
- offset_ = start; // repeat same edit descriptor next time
478
- } else {
479
- edit.repeat = stack_[height_ - 1 ].remaining ;
480
- --height_;
481
- }
482
- }
483
- }
484
433
return edit;
485
434
}
486
435
0 commit comments