Skip to content

Print numeric-looking strings verbatim - #541

Merged
bertysentry merged 8 commits into
mainfrom
fix/529-print-string-literals-verbatim
Jul 31, 2026
Merged

Print numeric-looking strings verbatim#541
bertysentry merged 8 commits into
mainfrom
fix/529-print-string-literals-verbatim

Conversation

@bertysentry

Copy link
Copy Markdown
Contributor

Fixes #529.

Problem

print numerically coerced any operand whose text parsed as a number, losing the original text:

$ jawk 'BEGIN { print "0100"; print "1e3"; print "+0100"; print "-0500" }'
100
1000
100
-500

This affected not only string constants but also input-sourced values: echo 0100 | jawk '{ print $1 }' printed 100, where gawk and POSIX AWK print 0100.

Root cause

AwkSink.normalizePrintArgument() converted every non-Number print operand whose toString() parsed as a BigDecimal into a Double before formatting, then applied OFMT. Per POSIX, print outputs string values (including strnums) unchanged; OFMT applies only when converting an actual number to a string.

Fix

  • Removed normalizePrintArgument(); formatPrintArgument() now formats real Numbers with the integer/OFMT rules and prints everything else verbatim via toString().
  • Corrected PosixIT.spec33OfmtVsConvfmt, whose 1.24 expectation encoded the buggy double conversion (s = x """1.235" via CONVFMT, then re-coerced and reformatted with OFMT). POSIX prints s verbatim: 1.235.
  • Added POSIX conformance tests: string constants verbatim, input fields verbatim, and OFMT applying to numbers only.

Verification

  • mvn verify passes: 639 unit tests, checkstyle/pmd/spotbugs clean.
  • gawk compatibility suite: 5 tests newly pass (test_fsfwfs, test_sortfor2, test_nasty2, test_numstr1, test_numsubstr); no regressions vs main (PosixIT.spec82NumericComparisonWithNumericStrings already failed on main).

🤖 Generated with Claude Code

Per POSIX, print must output string values unchanged; only actual
numbers are formatted with OFMT (or as integers). AwkSink used to
coerce any operand whose text parsed as a number into a double, so
print "0100" output 100 and input fields like $1 lost their original
text. Remove the coercion, fix the OFMT-vs-CONVFMT expectation that
relied on it, and add POSIX conformance tests. Fixes #529.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c8cca65f57

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

*/
protected final String formatPrintArgument(Object value, String ofmt) {
return formatOutputValue(normalizePrintArgument(value), ofmt, locale);
return formatOutputValue(value, ofmt, locale);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Document the changed print semantics

This changes user-visible AWK output for numeric-looking strings and for values converted with CONVFMT, but the commit updates neither README.md nor the site documentation. Add the new behavior to both documentation surfaces as required for end-user changes.

AGENTS.md reference: AGENTS.md:L34-L34

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Documented in 006b58e: added an "Output conversion in print" section to the compatibility page's Detailed Behavior Notes (covering verbatim string output, OFMT applying to numbers only, and CONVFMT vs OFMT). README.md intentionally unchanged: it stays high-level and already links to the compatibility page for detailed behavior notes, and this fix makes the behavior match the POSIX AWK support the README already claims.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@bertysentry

Copy link
Copy Markdown
Contributor Author

@codex please review again

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 🚀

Reviewed commit: 006b58eab2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Replaces the print-specific compatibility note with a dedicated site
page that documents the user-visible behavior changes of each Jawk
release, from newest to oldest, distilled from the GitHub release
notes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@bertysentry

Copy link
Copy Markdown
Contributor Author

@codex please review again

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 68cfd3ffd3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines 250 to +251
protected final String formatPrintArgument(Object value, String ofmt) {
return formatOutputValue(normalizePrintArgument(value), ofmt, locale);
return formatOutputValue(value, ofmt, locale);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve the released normalization helper

When a custom AwkSink compiled against Jawk 7.0 calls the protected normalizePrintArgument helper—whose Javadoc explicitly invited structured sinks to reuse it—removing the method makes an upgrade fail with NoSuchMethodError at runtime, while recompiling the sink also fails. Preserve the signature for binary/source compatibility, potentially as a deprecated identity implementation, while bypassing it in the built-in text sinks.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Restored in 910e088 as a @deprecated compatibility shim with its original conversion behavior, so sinks compiled against 7.0 keep working unchanged; the built-in text sinks bypass it.

Restores the protected helper removed earlier in this branch so custom
AwkSink subclasses compiled against 7.0 keep working; the built-in text
sinks no longer call it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@bertysentry

Copy link
Copy Markdown
Contributor Author

@codex please review again

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Breezy!

Reviewed commit: 910e0887b3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

The release workflow now renames the "Unreleased" section of
behavior-changes.md to the released version (and inserts a fresh stub)
before maven-release-plugin tags the release, so the page can never be
forgotten. AGENTS.md requires behavior-changing PRs to record their
change under "Unreleased", which Codex enforces in review.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@bertysentry

Copy link
Copy Markdown
Contributor Author

@codex please review again

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9598204d4b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

print "Unreleased"
print "----------"
print ""
print "_No user-visible behavior changes recorded yet._"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Remove the empty placeholder when stamping a nonempty release

After the first release, this generated sentence remains inside the new Unreleased section; when a later behavior-changing PR follows the documented workflow and adds a bullet without manually deleting it, the next run counts the bullet and moves both the placeholder and the bullet into the versioned section. The published history will therefore claim that the release has no user-visible changes immediately before listing one. Remove this placeholder when bullets > 0, or use a marker that is not carried into the released section.

AGENTS.md reference: AGENTS.md:L36-L36

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 3759c87: the stamping pass now drops the placeholder line (and its trailing blank) from the section being released, so only real bullets are carried into the versioned section. Verified with two consecutive stamp runs.

The fresh "Unreleased" stub's placeholder line was carried into the
next stamped release section alongside real bullets; the stamping pass
now removes it from the released section.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@bertysentry

Copy link
Copy Markdown
Contributor Author

@codex please review again

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3759c87715

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@@ -0,0 +1,94 @@
#!/usr/bin/env bash

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Add license headers to the new files

This commit adds .github/scripts/stamp-behavior-changes.sh and src/site/markdown/behavior-changes.md without the required project license header. Add the proper header to both new files before merging.

AGENTS.md reference: AGENTS.md:L7-L7

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not applicable per project convention: license headers are managed by license-maven-plugin, whose configuration covers only main/test/it/jmh Java sources, and the build's check-file-header gate (failOnMissingHeader=true) passes. No file in src/site/markdown or .github carries a header (a header would also render as visible text on the site page). AGENTS.md's instruction is operationalized by 'mvn license:update-file-header', which by configuration leaves these files untouched.

@bertysentry

Copy link
Copy Markdown
Contributor Author

@codex please review again

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Bravo.

Reviewed commit: 3759c87715

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

bertysentry and others added 2 commits July 31, 2026 17:53
Converts the page from setext underlines to #/## heading style and
adapts the release stamping script accordingly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@bertysentry

Copy link
Copy Markdown
Contributor Author

@codex please review again

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Delightful!

Reviewed commit: 70bbe64927

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@bertysentry
bertysentry merged commit 3f3c5e8 into main Jul 31, 2026
5 checks passed
@bertysentry
bertysentry deleted the fix/529-print-string-literals-verbatim branch July 31, 2026 16:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Numeric-looking string literals are printed as numbers (print "0100" outputs 100)

1 participant