Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
2138901
Reincorporate Printf4J as AwkPrintf with AWK printf semantics
bertysentry Aug 11, 2026
9a0004a
Address Codex review comments on AwkPrintf
bertysentry Aug 11, 2026
d75fde6
Address second round of Codex review comments on AwkPrintf
bertysentry Aug 11, 2026
30df61f
Address third round of Codex review comments on AwkPrintf
bertysentry Aug 11, 2026
bfb0cdd
Address fourth round of Codex review comments on AwkPrintf
bertysentry Aug 11, 2026
75294fa
Use the locale decimal separator in alternate %f/%e forms
bertysentry Aug 11, 2026
4cef883
Address sixth round of Codex review comments on AwkPrintf
bertysentry Aug 11, 2026
0dca6de
Fix checkstyle violation: fold grouping eligibility into Flags
bertysentry Aug 11, 2026
922d2de
Address seventh round of Codex review comments on AwkPrintf
bertysentry Aug 11, 2026
e7e2a7a
Address eighth round of Codex review comments on AwkPrintf
bertysentry Aug 11, 2026
b21491a
Treat zero-indexed star operands as zero, like gawk
bertysentry Aug 11, 2026
ab35dd3
Preserve legacy sprintf overrides in the CONVFMT bridge
bertysentry Aug 11, 2026
a50dc43
Avoid recursion through legacy sprintf overrides
bertysentry Aug 11, 2026
08b0731
Reject positional formats in POSIX mode and unterminated star digits
bertysentry Aug 11, 2026
6b2c6b8
Lean printf API: CONVFMT in printf(), no compatibility bridges
bertysentry Aug 12, 2026
c174b09
Simplify printf plumbing and add JavaStringFormatAwkSink
bertysentry Aug 13, 2026
ec8dbc5
Map AWK values to natural Java types in JavaStringFormatAwkSink
bertysentry Aug 13, 2026
e47c80c
Clarify AGENTS.md: AwkTestSupport is for script-running tests only
bertysentry Aug 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,13 @@ Whenever required, when you add code or when you modify code that is not covered

Compatibility tests are run with `mvn verify` to assess the compatibility with other implementations of AWK. These tests are run with the Maven failsafe plugin and results are stored in the ./target/failsafe-reports directory.

All new or updated unit tests must use the helper methods in
`org.metricshub.jawk.AwkTestSupport`. The builders in that class encapsulate the
correct Jawk setup, assertion flow, and temporary file handling, so reusing
them keeps the test suite consistent and reliable.
All new or updated unit tests that run AWK scripts must use the helper methods
in `io.jawk.AwkTestSupport`. The builders in that class encapsulate the correct
Jawk setup, assertion flow, and temporary file handling, so reusing them keeps
the test suite consistent and reliable. `AwkTestSupport` is ONLY for running
AWK scripts and assessing their results: unit tests for regular Java methods
call those methods directly with plain JUnit assertions, and no non-script
assertion helpers may be added to `AwkTestSupport`.

## Code quality reports

Expand Down
6 changes: 0 additions & 6 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,6 @@

<dependencies>

<dependency>
<groupId>org.metricshub</groupId>
<artifactId>printf4j</artifactId>
<version>0.9.08</version>
</dependency>

<dependency>
<groupId>com.github.stefanbirkner</groupId>
<artifactId>system-rules</artifactId>
Expand Down
7 changes: 3 additions & 4 deletions src/main/java/io/jawk/backend/AVM.java
Original file line number Diff line number Diff line change
Expand Up @@ -1785,7 +1785,7 @@ private void executeTuples(PositionTracker position)
}
case INTFUNC: {
// stack[0] = arg to int() function
push((long) JRT.toDouble(pop()));
push(JRT.truncateToScalar(JRT.toDouble(pop())));
position.next();
break;
}
Expand Down Expand Up @@ -3003,7 +3003,7 @@ private Object invokeIndirectBuiltin(
return jrt.index(jrt.toAwkString(args[0]), jrt.toAwkString(args[1]));
case INT:
requireIndirectArgumentCount(builtin, args, 1, 1, lineNumber);
return Long.valueOf((long) JRT.toDouble(args[0]));
return JRT.truncateToScalar(JRT.toDouble(args[0]));
case LENGTH:
requireIndirectArgumentCount(builtin, args, 0, 1, lineNumber);
return args.length == 0 ? Integer.valueOf(jrt.jrtGetInputField(0).toString().length()) : lengthOf(args[0]);
Expand All @@ -3029,7 +3029,6 @@ private Object invokeIndirectBuiltin(
case SPRINTF:
requireIndirectArgumentCount(builtin, args, 1, Integer.MAX_VALUE, lineNumber);
return jrt
.getAwkSink()
.sprintf(
jrt.toAwkString(args[0]),
Arrays.copyOfRange(args, 1, args.length));
Expand Down Expand Up @@ -3784,7 +3783,7 @@ private Object[] popArguments(long numArgs) {
private String sprintfFunction(long numArgs) {
Object[] argArray = popArguments(numArgs - 1);
String fmt = jrt.toAwkString(pop());
return jrt.getAwkSink().sprintf(fmt, argArray);
return jrt.sprintf(fmt, argArray);
}

private void setNumOnJRT(long fieldNum, double num) {
Expand Down
48 changes: 12 additions & 36 deletions src/main/java/io/jawk/intermediate/AwkTuples.java
Original file line number Diff line number Diff line change
Expand Up @@ -2383,55 +2383,37 @@ private Object foldBinary(Object left, Object right, Tuple operation) {
double d1 = JRT.toDouble(left);
double d2 = JRT.toDouble(right);
double ans = d1 + d2;
if (JRT.isActuallyLong(ans)) {
return Long.valueOf((long) Math.rint(ans));
}
return Double.valueOf(ans);
return JRT.toScalarNumber(ans);
}
case SUBTRACT: {
double d1 = JRT.toDouble(left);
double d2 = JRT.toDouble(right);
double ans = d1 - d2;
if (JRT.isActuallyLong(ans)) {
return Long.valueOf((long) Math.rint(ans));
}
return Double.valueOf(ans);
return JRT.toScalarNumber(ans);
}
case MULTIPLY: {
double d1 = JRT.toDouble(left);
double d2 = JRT.toDouble(right);
double ans = d1 * d2;
if (JRT.isActuallyLong(ans)) {
return Long.valueOf((long) Math.rint(ans));
}
return Double.valueOf(ans);
return JRT.toScalarNumber(ans);
}
case DIVIDE: {
double d1 = JRT.toDouble(left);
double d2 = JRT.toDouble(right);
double ans = d1 / d2;
if (JRT.isActuallyLong(ans)) {
return Long.valueOf((long) Math.rint(ans));
}
return Double.valueOf(ans);
return JRT.toScalarNumber(ans);
}
case MOD: {
double d1 = JRT.toDouble(left);
double d2 = JRT.toDouble(right);
double ans = d1 % d2;
if (JRT.isActuallyLong(ans)) {
return Long.valueOf((long) Math.rint(ans));
}
return Double.valueOf(ans);
return JRT.toScalarNumber(ans);
}
case POW: {
double d1 = JRT.toDouble(left);
double d2 = JRT.toDouble(right);
double ans = Math.pow(d1, d2);
if (JRT.isActuallyLong(ans)) {
return Long.valueOf((long) Math.rint(ans));
}
return Double.valueOf(ans);
return JRT.toScalarNumber(ans);
}
case CMP_EQ:
case CMP_LT:
Expand Down Expand Up @@ -2462,17 +2444,11 @@ private Object foldUnary(Object literal, Tuple operation) {
case NEGATE: {
double value = JRT.toDouble(literal);
double ans = -value;
if (JRT.isActuallyLong(ans)) {
return Long.valueOf((long) Math.rint(ans));
}
return Double.valueOf(ans);
return JRT.toScalarNumber(ans);
}
case UNARY_PLUS: {
double value = JRT.toDouble(literal);
if (JRT.isActuallyLong(value)) {
return Long.valueOf((long) Math.rint(value));
}
return Double.valueOf(value);
return JRT.toScalarNumber(value);
}
default:
return null;
Expand All @@ -2488,11 +2464,11 @@ private Tuple createLiteralPush(Object value, int lineNumber) {
} else if (value instanceof Double) {
tuple = new Tuple.PushDoubleTuple(((Double) value).doubleValue());
} else if (value instanceof Number) {
double d = ((Number) value).doubleValue();
if (JRT.isActuallyLong(d)) {
tuple = new Tuple.PushLongTuple((long) Math.rint(d));
Object scalar = JRT.toScalarNumber(((Number) value).doubleValue());
if (scalar instanceof Long) {
tuple = new Tuple.PushLongTuple(((Long) scalar).longValue());
} else {
tuple = new Tuple.PushDoubleTuple(d);
tuple = new Tuple.PushDoubleTuple(((Double) scalar).doubleValue());
}
} else if (value instanceof String) {
tuple = new Tuple.PushStringTuple((String) value);
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/io/jawk/jrt/AppendableAwkSink.java
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,10 @@ public void print(String ofs, String ors, String ofmt, Object... values) throws
}

@Override
public void printf(String ofs, String ors, String ofmt, String format, Object... values)
public void printf(String ofs, String ors, String ofmt, String convfmt, String format, Object... values)
throws IOException {
synchronized (lock) {
appendable.append(formatPrintfResult(format, values));
appendable.append(sprintf(convfmt, format, values));
}
}

Expand Down
Loading
Loading