@@ -13,9 +13,30 @@ public static ParseResult parse(String format) {
13
13
int start = parser .pos ;
14
14
15
15
if (parser .current () == '%' ) {
16
+ int savedPos = parser .pos ; // Save position before parsing
16
17
FormatSpecifier spec = parser .parseSpecifier ();
17
18
if (spec != null ) {
18
19
result .addSpecifier (spec );
20
+
21
+ // Special case: if the format ends with % as conversion char,
22
+ // check if that % starts another invalid format (for warning only)
23
+ if (spec .conversionChar == '%' && !spec .isValid && !parser .isAtEnd ()) {
24
+ // Temporarily parse from the second % to check for invalid format
25
+ int currentPos = parser .pos ;
26
+ parser .pos = savedPos + spec .raw .length () - 1 ;
27
+
28
+ if (parser .current () == '%' ) {
29
+ FormatSpecifier overlapSpec = parser .parseSpecifier ();
30
+ if (overlapSpec != null && !overlapSpec .isValid ) {
31
+ // Mark as overlapping - generate warning but not output
32
+ overlapSpec .isOverlapping = true ;
33
+ result .addSpecifier (overlapSpec );
34
+ }
35
+ }
36
+
37
+ // Restore original position
38
+ parser .pos = currentPos ;
39
+ }
19
40
} else {
20
41
// Failed to parse, add % as literal
21
42
result .addLiteral ("%" );
@@ -70,6 +91,7 @@ public static class FormatSpecifier {
70
91
public char conversionChar ;
71
92
public boolean isValid = true ;
72
93
public String errorMessage ;
94
+ public boolean isOverlapping = false ; // Don't include in output, just warn
73
95
}
74
96
75
97
private static class Parser {
@@ -277,11 +299,17 @@ FormatSpecifier parseSpecifier() {
277
299
} else {
278
300
spec .conversionChar = current ();
279
301
advance ();
302
+ System .err .println ("DEBUG: Parsed conversion char '" + spec .conversionChar + "'" );
280
303
}
281
304
282
305
spec .endPos = pos ;
283
306
spec .raw = input .substring (spec .startPos , spec .endPos );
284
307
308
+ // ADD DEBUG HERE:
309
+ System .err .println ("DEBUG parseSpecifier: raw='" + spec .raw +
310
+ "', vectorFlag=" + spec .vectorFlag +
311
+ ", conversionChar='" + spec .conversionChar + "'" );
312
+
285
313
// Add debug here to check the state before returning
286
314
// System.err.println("DEBUG: Before return - isValid=" + spec.isValid +
287
315
// ", errorMessage='" + spec.errorMessage + "'");
@@ -331,19 +359,19 @@ void validateSpecifier(FormatSpecifier spec) {
331
359
return ;
332
360
}
333
361
334
- // Check for vector formats FIRST (before %n check)
335
- if (spec .vectorFlag ) {
336
- // Vector flag is only valid with certain conversions
337
- String validVectorConversions = "diouxXbB" ; // Remove 's'
338
- // System.err.println("DEBUG: Checking vector conversion '" + spec.conversionChar +
339
- // "' in '" + validVectorConversions + "'");
340
- if (validVectorConversions .indexOf (spec .conversionChar ) < 0 ) {
341
- // System.err.println("DEBUG: Setting invalid for vector format");
342
- spec .isValid = false ;
343
- spec .errorMessage = "INVALID" ;
344
- return ;
345
- }
346
- }
362
+ // Check for vector formats FIRST (before %n check)
363
+ if (spec .vectorFlag ) {
364
+ // Vector flag is only valid with certain conversions
365
+ String validVectorConversions = "diouxXbB" ;
366
+ System .err .println ("DEBUG: Checking vector conversion '" + spec .conversionChar +
367
+ "' in '" + validVectorConversions + "'" );
368
+ if (validVectorConversions .indexOf (spec .conversionChar ) < 0 ) {
369
+ System .err .println ("DEBUG: Setting invalid for vector format" );
370
+ spec .isValid = false ;
371
+ spec .errorMessage = "INVALID" ;
372
+ return ;
373
+ }
374
+ }
347
375
348
376
if ("V" .equals (spec .lengthModifier )) {
349
377
// V is silently ignored in Perl
0 commit comments