Skip to content

Commit 246a2f0

Browse files
committed
fix sprintf WIP
1 parent 0677153 commit 246a2f0

1 file changed

Lines changed: 39 additions & 17 deletions

File tree

src/main/java/org/perlonjava/operators/SprintfOperator.java

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,10 @@ public static RuntimeScalar sprintf(RuntimeScalar runtimeScalar, RuntimeList lis
5959
result.append(literal);
6060
charsWritten += literal.length();
6161
} else if (element instanceof FormatSpecifier spec) {
62+
System.err.println("DEBUG: Processing spec: " + spec.raw + ", isValid=" + spec.isValid);
6263
// Check if this is an overlapping specifier (warning only, no output)
6364
if (spec.isOverlapping) {
65+
System.err.println("DEBUG: Skipping overlapping spec");
6466
// Only generate warning, don't add to output
6567
if (!spec.isValid) {
6668
// Just generate the warning, don't add to result
@@ -72,6 +74,7 @@ public static RuntimeScalar sprintf(RuntimeScalar runtimeScalar, RuntimeList lis
7274

7375
// Check if spec is invalid FIRST
7476
if (!spec.isValid) {
77+
System.err.println("DEBUG: Processing invalid spec");
7578
String formatted = processFormatSpecifier(spec, list, argIndex, formatter);
7679
result.append(formatted);
7780
charsWritten += formatted.length();
@@ -109,6 +112,7 @@ public static RuntimeScalar sprintf(RuntimeScalar runtimeScalar, RuntimeList lis
109112
continue; // Skip to next format element
110113
} else {
111114
ProcessResult processResult = processFormatSpecifierTracked(spec, list, argIndex, formatter);
115+
System.err.println("DEBUG: Called processFormatSpecifierTracked");
112116
result.append(processResult.formatted);
113117
charsWritten += processResult.formatted.length();
114118

@@ -186,16 +190,17 @@ private static void handlePercentN(FormatSpecifier spec,
186190
/**
187191
* Process a single format specifier with tracking.
188192
*/
189-
private static ProcessResult processFormatSpecifierTracked(
190-
FormatSpecifier spec,
191-
RuntimeList list,
192-
int sepArgIndex,
193-
SprintfValueFormatter formatter) {
193+
private static ProcessResult processFormatSpecifierTracked(
194+
FormatSpecifier spec,
195+
RuntimeList list,
196+
int sepArgIndex,
197+
SprintfValueFormatter formatter) {
194198

195-
String formatted = processFormatSpecifier(spec, list, sepArgIndex, formatter, -1);
199+
System.err.println("DEBUG: processFormatSpecifierTracked called for: " + spec.raw);
200+
String formatted = processFormatSpecifier(spec, list, sepArgIndex, formatter, -1);
196201

197-
// Calculate max arg index used
198-
int maxUsed = -1;
202+
// Calculate max arg index used
203+
int maxUsed = -1;
199204

200205
// Handle %% - literal percent sign
201206
if (spec.conversionChar == '%') {
@@ -236,9 +241,6 @@ private static ProcessResult processFormatSpecifierTracked(
236241
return new ProcessResult(formatted, maxUsed);
237242
}
238243

239-
// Track all consumed arguments properly
240-
FormatArguments args = extractFormatArguments(spec, list, sepArgIndex);
241-
242244
// Track width argument if consumed
243245
if (spec.widthFromArg) {
244246
if (spec.widthArgIndex != null) {
@@ -273,8 +275,13 @@ private static ProcessResult processFormatSpecifierTracked(
273275
}
274276

275277
// Track value argument
276-
if (args.valueArgIndex < list.size()) {
277-
maxUsed = Math.max(maxUsed, args.valueArgIndex);
278+
if (spec.parameterIndex != null) {
279+
maxUsed = Math.max(maxUsed, spec.parameterIndex - 1);
280+
} else {
281+
int valuePos = sepArgIndex;
282+
if (spec.widthFromArg && spec.widthArgIndex == null) valuePos++;
283+
if (spec.precisionFromArg && spec.precisionArgIndex == null) valuePos++;
284+
maxUsed = Math.max(maxUsed, valuePos);
278285
}
279286

280287
return new ProcessResult(formatted, maxUsed);
@@ -297,7 +304,7 @@ private static String processFormatSpecifier(
297304
SprintfValueFormatter formatter,
298305
int maxArgIndexUsed) {
299306

300-
// System.err.println("DEBUG processFormatSpecifier: raw='" + spec.raw + "', isValid=" + spec.isValid + ", errorMessage=" + spec.errorMessage);
307+
System.err.println("DEBUG: processFormatSpecifier start for: " + spec.raw);
301308

302309
// Handle invalid specifiers FIRST (before %% check)
303310
if (!spec.isValid) {
@@ -307,6 +314,7 @@ private static String processFormatSpecifier(
307314
// Handle %% - literal percent sign
308315
if (spec.conversionChar == '%') {
309316
if (spec.widthFromArg) {
317+
System.err.println("DEBUG: About to call extractFormatArguments");
310318
FormatArguments args = extractFormatArguments(spec, list, sepArgIndex);
311319
// Consume the width argument but still return %
312320
}
@@ -319,6 +327,7 @@ private static String processFormatSpecifier(
319327
}
320328

321329
// Process width, precision, and value arguments
330+
System.err.println("DEBUG: About to call extractFormatArguments");
322331
FormatArguments args = extractFormatArguments(spec, list, sepArgIndex);
323332

324333
// Check for missing value argument
@@ -399,15 +408,21 @@ private static FormatArguments extractFormatArguments(
399408
RuntimeList list,
400409
int argIndex) {
401410

411+
System.err.println("DEBUG: extractFormatArguments start - argIndex=" + argIndex);
412+
System.err.println("DEBUG: spec.widthFromArg=" + spec.widthFromArg + ", spec.widthArgIndex=" + spec.widthArgIndex);
413+
402414
FormatArguments args = new FormatArguments();
403415
int currentArgIndex = argIndex;
404416

405417
// Process width
406418
if (spec.widthFromArg) {
407419
int widthArgIndex;
408420
if (spec.widthArgIndex != null) {
409-
// Explicit index like %*2$d
421+
// Explicit index like %*2$d - positional parameter
410422
widthArgIndex = spec.widthArgIndex - 1;
423+
System.err.println("DEBUG: Positional width at index " + widthArgIndex);
424+
// DON'T increment currentArgIndex or consumedArgs for positional
425+
// because it's not consuming from the sequential stream
411426
} else if (spec.parameterIndex != null) {
412427
// When we have %2$*d, the width comes from the current position
413428
widthArgIndex = currentArgIndex;
@@ -434,12 +449,15 @@ private static FormatArguments extractFormatArguments(
434449
args.width = spec.width;
435450
}
436451

437-
// Process precision
452+
System.err.println("DEBUG: After width processing: consumedArgs=" + args.consumedArgs);
453+
454+
// Process precision (similar logic)
438455
if (spec.precisionFromArg) {
439456
int precArgIndex;
440457
if (spec.precisionArgIndex != null) {
441-
// Explicit index like %.*2$d
458+
// Explicit index like %.*2$d - positional parameter
442459
precArgIndex = spec.precisionArgIndex - 1;
460+
// DON'T increment currentArgIndex or consumedArgs for positional
443461
} else if (spec.parameterIndex != null) {
444462
// When we have %2$.*d, precision comes from current position
445463
precArgIndex = currentArgIndex;
@@ -465,13 +483,17 @@ private static FormatArguments extractFormatArguments(
465483
args.precision = spec.precision;
466484
}
467485

486+
System.err.println("DEBUG: Before valueArgIndex calc - argIndex=" + argIndex + ", consumedArgs=" + args.consumedArgs);
487+
468488
// Determine value argument index
469489
if (spec.parameterIndex != null) {
470490
args.valueArgIndex = spec.parameterIndex - 1;
471491
} else {
472492
args.valueArgIndex = argIndex + args.consumedArgs;
473493
}
474494

495+
System.err.println("DEBUG: Calculated valueArgIndex=" + args.valueArgIndex + ", list.size()=" + list.size());
496+
475497
return args;
476498
}
477499

0 commit comments

Comments
 (0)