Skip to content

feat(libc): export std::numpunct<wchar_t> id and _Getcat - #11773

Merged
oneandonlydean merged 2 commits into
boykopovar:mainfrom
edubox:feat/libc-numpunct-wide
Nov 2, 2026
Merged

oneandonlydean merged 2 commits into
boykopovar:mainfrom
edubox:feat/libc-numpunct-wide

Conversation

@edubox

@edubox edubox commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

What

Export std::numpunct<wchar_t>::id (XZNi3XtbWQ4) and implement std::numpunct<wchar_t>::_Getcat (SdXFaufpLIs), the two unversioned libc symbols that the libc.prx of Rayman 30 Aniversario (PPSA33016) and Fatal Frame II (PPSA32802) import and AnyPS5 does not export.

The facet is the same 0x30-byte C-locale object as the narrow numpunct<char>: grouping is a narrow string pointer at offset 0x10, falsename and truename are pointers to 16-bit strings at offsets 0x20 and 0x28, and decimal_point and thousands_sep are 16-bit values at 0x18 and 0x1a. The grouping virtual writes the narrow string with the narrow size and capacity rules (inline capacity 15, heap capacity length | 15), while falsename and truename write the guest 16-bit string with the same rules as collate<wchar_t>::do_transform (inline capacity 7, heap capacity length | 7, two bytes per unit). _Getcat returns 4, as the narrow entry does.

Console evidence: in the libc.prx shipped by PPSA33016 (unwrapped, dynsym), XZNi3XtbWQ4 is an 8-byte STT_OBJECT in .data, and SdXFaufpLIs is a 0x17b-byte function at 0xa2670 that allocates 0x30 bytes, stores the vtable, the empty grouping string, 16-bit '.' and ',', pointers to the 16-bit strings "false" and "true", and returns 4.

Tested

  • guest_locale_tests passes. The new checks cover the wide id's 8-byte size, the facet's 16-bit ./,, the narrow empty grouping, and the 16-bit "false"/"true".
  • Rayman 30 Aniversario PPSA33016: with this change the title resolves both NIDs and loads; it presented 11 frames in 120 s with no undefined symbol or crash. The title also imports the _Cnd_register_at_thread_exit/_Cnd_unregister_at_thread_exit pair, so that run used a local build that includes those registrations; this PR does not depend on that work.
  • Fatal Frame II PPSA32802 imports the same two NIDs, but its run aborts later in a guest formatting path (__stack_chk_fail) that never reaches the wide facet, so it is not used as evidence here.

Checklist

  • Based on current main; no other open PR implements the same functions
  • One topic per PR; follow-ups go in a new PR
  • No comments in code except technical debt
  • Unimplemented paths throw (NotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file
  • No notes, investigation .md files or images added to the repository (attach them to this PR)
  • New third-party code is a submodule built from source
  • Generic behaviour, not specific to one title
  • Depends on: none
  • Fixes: none
  • Unblocks: none (PPSA33016 and PPSA32802 import these NIDs; neither has a Game bring-up discussion)
  • GPUs tested: n/a
  • AI-assisted: yes

@github-actions

github-actions Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

Progress report (ba62780 → 014001a)

📈 System libraries: 26.25% (+0.01%, +7 implemented functions)

✅ 7 implemented
Library Name
libc AssignWideCString
libc WideNumpunctDecimalPoint
libc WideNumpunctFalsename
libc WideNumpunctGrouping
libc WideNumpunctThousandsSep
libc WideNumpunctTruename
libc _ZNSt8numpunctIwE7_GetcatEPPKNSt6locale5facetEPKS1__nid_postfix

Changed libraries (implemented exports)

Library Before After Change
libc 1489/1505 (98.94%) 1496/1512 (98.94%) +0.0049%

@edubox
edubox force-pushed the feat/libc-numpunct-wide branch from d966bfd to 97f4f6c Compare October 27, 2026 08:07
@edubox

edubox commented Oct 27, 2026

Copy link
Copy Markdown
Contributor Author

Rebased onto current main (1b2af92baf); head is now 97f4f6c3b0. guest_locale_tests passes and check_conventions.py --base origin/main plus git diff --check are clean.

@github-actions

github-actions Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

Other open pull requests touch the same code. Merging one will break the other, or both implement the same thing. If this one builds on them, list them in Depends on.

Pull request Conflicting files (lines on main) Same exports Same new files
PR 11172 core/libs/prx/libc/src/LocaleSupport.cpp L243-260

Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.

Pull request Shared files not compared
PR 5021 docs/dev/debt/libc.md
PR 5303 docs/dev/debt/libc.md
PR 6565 docs/dev/debt/libc.md
PR 7081 core/libs/prx/libc/src/LocaleSupport.cpp
docs/dev/debt/libc.md
PR 7386 docs/dev/debt/libc.md
PR 7447 docs/dev/debt/libc.md
PR 7715 docs/dev/debt/libc.md
PR 8150 docs/dev/debt/libc.md
PR 8965 docs/dev/debt/libc.md
PR 9340 docs/dev/debt/libc.md
PR 9371 docs/dev/debt/libc.md
PR 9447 docs/dev/debt/libc.md
PR 9526 core/libs/prx/libc/src/LocaleSupport.cpp
core/libs/tests/GuestLocale.cpp
docs/dev/debt/libc.md
PR 9929 docs/dev/debt/libc.md
PR 9964 docs/dev/debt/libc.md
PR 10113 docs/dev/debt/libc.md
PR 10226 docs/dev/debt/libc.md
PR 10245 docs/dev/debt/libc.md
PR 10250 docs/dev/debt/libc.md
PR 10253 docs/dev/debt/libc.md
PR 10265 docs/dev/debt/libc.md
PR 10274 docs/dev/debt/libc.md
PR 10315 docs/dev/debt/libc.md
PR 10325 docs/dev/debt/libc.md
PR 10328 docs/dev/debt/libc.md
PR 10345 docs/dev/debt/libc.md
PR 10349 docs/dev/debt/libc.md
PR 10405 docs/dev/debt/libc.md
PR 10506 docs/dev/debt/libc.md
PR 10510 docs/dev/debt/libc.md
PR 10512 docs/dev/debt/libc.md
PR 10565 docs/dev/debt/libc.md
PR 10987 docs/dev/debt/libc.md
PR 11260 docs/dev/debt/libc.md
PR 11262 docs/dev/debt/libc.md
PR 11266 docs/dev/debt/libc.md
PR 11332 docs/dev/debt/libc.md
PR 11831 core/libs/prx/libc/include/Api.hpp
docs/dev/debt/libc.md
PR 11907 docs/dev/debt/libc.md
PR 12057 docs/dev/debt/libc.md
PR 12122 docs/dev/debt/libc.md
PR 12292 docs/dev/debt/libc.md
PR 12397 docs/dev/debt/libc.md
PR 12514 docs/dev/debt/libc.md
PR 12560 docs/dev/debt/libc.md
PR 12574 docs/dev/debt/libc.md
PR 12627 docs/dev/debt/libc.md
PR 13390 docs/dev/debt/libc.md
PR 13804 docs/dev/debt/libc.md
PR 14212 docs/dev/debt/libc.md

@edubox

edubox commented Oct 27, 2026

Copy link
Copy Markdown
Contributor Author

Rebased automatically onto current main (5bc84038c4); head is now c52c52f602. Focused tests pass; check_conventions.py --base origin/main and git diff --check are clean.

@edubox
edubox force-pushed the feat/libc-numpunct-wide branch from 97f4f6c to c52c52f Compare October 27, 2026 09:01
@oneandonlydean

Copy link
Copy Markdown
Collaborator

@edubox thanks, the layout and vtable order match Dinkumware's numpunct, and the wide falsename/truename are right. One blocker and one small fix:

  1. grouping must stay narrow for numpunct<wchar_t>: the standard has string grouping() const for both facets, and the pinned Dinkumware xlocnum keeps const char* _Grouping and string do_grouping() (only the two names use string_type). WideNumpunctGrouping currently builds it through AssignWideCString, so even the empty C-locale grouping gets the wide representation. Please use the narrow storage/result path (as AssignCString does), have the grouping check verify the narrow representation rather than only size() == 0, and correct the debt paragraph that calls grouping 16-bit.
  2. LocaleSupport.cpp has a local extern for the id that Api.hpp already declares. Each export needs exactly one declaration (the public-header rule), so please drop the local one and include the header.

No other changes requested; _Getcat's measured signature stays as it is.

@edubox

edubox commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor Author

Addressed the review on 7d0f2a2f58:

  • numpunct<wchar_t>::grouping now stores and returns a narrow string (const char* with AssignCString); the test checks the narrow inline capacity (15) and terminator instead of only size() == 0, and the debt entry no longer describes grouping as a 16-bit string.
  • Removed the local _ZNSt8numpunctIwE2idE_nid_postfix extern; the declaration in Api.hpp is now the only one.

Verified: guest_locale passes, check_conventions.py --base origin/main passes, and git diff --check is clean.

AI-assisted: yes

@edubox
edubox force-pushed the feat/libc-numpunct-wide branch from 4670904 to 7d0f2a2 Compare October 27, 2026 10:05
@edubox

edubox commented Oct 27, 2026

Copy link
Copy Markdown
Contributor Author

Rebased automatically onto current main (486919e70a); head is now 1c77eb06ec. Focused tests pass; check_conventions.py --base origin/main and git diff --check are clean.

@edubox
edubox force-pushed the feat/libc-numpunct-wide branch 2 times, most recently from 1c77eb0 to 37ee72b Compare October 27, 2026 12:02
@edubox

edubox commented Oct 27, 2026

Copy link
Copy Markdown
Contributor Author

Rebased automatically onto current main (ca0e9557aa); head is now 37ee72bf5a. Focused tests pass; check_conventions.py --base origin/main and git diff --check are clean.

@edubox

edubox commented Oct 27, 2026

Copy link
Copy Markdown
Contributor Author

Rebased automatically onto current main (62b3ba2522); head is now e654d6ef6d. Focused tests pass; check_conventions.py --base origin/main and git diff --check are clean.

@edubox
edubox force-pushed the feat/libc-numpunct-wide branch from 37ee72b to e654d6e Compare October 27, 2026 13:02
@edubox

edubox commented Oct 27, 2026

Copy link
Copy Markdown
Contributor Author

Rebased automatically onto current main (75f3702aed); head is now e4d0f50b53. Focused tests pass; check_conventions.py --base origin/main and git diff --check are clean.

@edubox
edubox force-pushed the feat/libc-numpunct-wide branch from e654d6e to e4d0f50 Compare October 27, 2026 14:02
@maskym

maskym commented Oct 27, 2026

Copy link
Copy Markdown
Contributor

Windows result for head e4d0f50b53, merged into main 75f3702aed (the PR's Tested section names no Windows run).

Host: Windows 11 26300, Intel i7-12700K, WinLibs GCC 15.2.0 (x86_64-ucrt-posix-seh, r6), Release, BUILD_TESTING=ON, Ninja. Build clean.

The tree also carried the open libc PRs #11793, #11890, #11843 and #11846, all merged cleanly, so the run is a joint one; the test of this PR is guest_locale, which passed in 0.05 s (ctest --test-dir build -R "^guest_locale$"). Not run on a PS5.

AI-assisted: yes (Claude Code), the runs and the numbers above are from this machine.

@edubox

edubox commented Oct 27, 2026

Copy link
Copy Markdown
Contributor Author

Rebased automatically onto current main (0c4a8cb41a); head is now d54b9006de. Focused tests pass; check_conventions.py --base origin/main and git diff --check are clean.

@edubox
edubox force-pushed the feat/libc-numpunct-wide branch 2 times, most recently from d54b900 to 25812b3 Compare October 27, 2026 18:02
@edubox

edubox commented Oct 27, 2026

Copy link
Copy Markdown
Contributor Author

Rebased automatically onto current main (14332cd8d0); head is now 25812b316c. Focused tests pass; check_conventions.py --base origin/main and git diff --check are clean.

@edubox

edubox commented Oct 27, 2026

Copy link
Copy Markdown
Contributor Author

Rebased automatically onto current main (46fe6f2437); head is now 382e8d5ca0. Focused tests pass; check_conventions.py --base origin/main and git diff --check are clean.

@edubox
edubox force-pushed the feat/libc-numpunct-wide branch from 25812b3 to 382e8d5 Compare October 27, 2026 21:02
@edubox

edubox commented Oct 31, 2026

Copy link
Copy Markdown
Contributor Author

Rebased automatically onto current main (2364892547); head is now aa51c3bb69. Focused tests pass; check_conventions.py --base origin/main and git diff --check are clean.

@edubox
edubox force-pushed the feat/libc-numpunct-wide branch from c9be277 to aa51c3b Compare October 31, 2026 04:02
@edubox

edubox commented Oct 31, 2026

Copy link
Copy Markdown
Contributor Author

Rebased automatically onto current main (3d1330179a); head is now 2ce4d516ed. Focused tests pass; check_conventions.py --base origin/main and git diff --check are clean.

@edubox
edubox force-pushed the feat/libc-numpunct-wide branch from aa51c3b to 2ce4d51 Compare October 31, 2026 05:03
@edubox

edubox commented Oct 31, 2026

Copy link
Copy Markdown
Contributor Author

Rebased automatically onto current main (de83e8f270); head is now 0fb5a3abd1. Focused tests pass; check_conventions.py --base origin/main and git diff --check are clean.

@edubox
edubox force-pushed the feat/libc-numpunct-wide branch from 2ce4d51 to 0fb5a3a Compare October 31, 2026 07:03
@edubox

edubox commented Oct 31, 2026

Copy link
Copy Markdown
Contributor Author

Status on head 0fb5a3abd1: both review points are already in this head.

  • WideNumpunctGrouping now uses AssignCString, so grouping keeps the narrow storage and result rules (inline capacity 15), and the test checks that narrow representation (size == 0, capacity == 15, buffer[0] == '\0'). The debt entry now says grouping is a narrow pointer at 0x10.
  • The local extern for _ZNSt8numpunctIwE2idE_nid_postfix is gone; Api.hpp is included and carries the single declaration.

Verified on this machine: guest_locale passes, and python3 tools/check_conventions.py --base origin/main plus git diff --check are clean. The two failing write-watch jobs are not from this PR: core/libs/tests/write_watch/CMakeLists.txt on main registers write_watch_execute-fault and write_watch_read-fault twice, and #13220 removes the duplicate block. Branch left unchanged; no rebase or push.

AI-assisted: yes

@edubox

edubox commented Oct 31, 2026

Copy link
Copy Markdown
Contributor Author

Rebased automatically onto current main (45f4f82449); head is now 8e4a93402e. Focused tests pass; check_conventions.py --base origin/main and git diff --check are clean.

@edubox
edubox force-pushed the feat/libc-numpunct-wide branch from 0fb5a3a to 8e4a934 Compare October 31, 2026 10:02
@edubox

edubox commented Oct 31, 2026

Copy link
Copy Markdown
Contributor Author

Rebased automatically onto current main (1847a6f9da); head is now e60cd0b4cb. Focused tests pass; check_conventions.py --base origin/main and git diff --check are clean.

@edubox
edubox force-pushed the feat/libc-numpunct-wide branch from 8e4a934 to e60cd0b Compare October 31, 2026 11:04
@edubox

edubox commented Oct 31, 2026

Copy link
Copy Markdown
Contributor Author

Watchdog status on e60cd0b4cb: both review points are already in this head, so nothing is pushed.

  • WideNumpunctGrouping uses AssignCString, so grouping keeps the narrow storage and result rules. The test now checks the narrow representation (capacity == 15, buffer[0] == '\0'), and the debt paragraph describes the narrow grouping.
  • The local extern for the id is gone; Api.hpp is the single declaration.
  • guest_locale passes; check_conventions.py --base origin/main and git diff --check are clean.
  • The two write-watch failures are not from this patch: main registers write_watch_execute-fault and write_watch_read-fault twice in core/libs/tests/write_watch/CMakeLists.txt. test(libc): register the macOS write watch fault tests once #13220 fixes that registration and is owned by another author.

@edubox

edubox commented Oct 31, 2026

Copy link
Copy Markdown
Contributor Author

Rebased automatically onto current main (b8f0a6b202); head is now 7bacb3d9aa. Focused tests pass; check_conventions.py --base origin/main and git diff --check are clean.

@edubox
edubox force-pushed the feat/libc-numpunct-wide branch from e60cd0b to 7bacb3d Compare October 31, 2026 12:03
@edubox

edubox commented Oct 31, 2026

Copy link
Copy Markdown
Contributor Author

Watchdog status on 7bacb3d9aa: both review points are already in this head, so nothing is pushed.

  • WideNumpunctGrouping uses AssignCString, so grouping keeps the narrow storage and result rules. The test checks the narrow representation (capacity == 15, buffer[0] == '\0'), and the debt paragraph describes the narrow grouping.
  • The local extern for the id is gone; Api.hpp is the single declaration.
  • The #11504 overlap raised by @verusferro is resolved: feat(libc): throw std::filesystem::filesystem_error from _Xfilesystem_error as the console's libc does #11504 merged on 2026-10-29, this head is rebased on b8f0a6b202, and both calls use GuestLocale::AllocateStringStorage.
  • guest_locale passes; check_conventions.py --base origin/main and git diff --check are clean.
  • The two write-watch failures are not from this patch: main registers write_watch_execute-fault and write_watch_read-fault twice in core/libs/tests/write_watch/CMakeLists.txt. test(libc): register the macOS write watch fault tests once #13220 fixes that registration and is owned by another author.

@edubox

edubox commented Oct 31, 2026

Copy link
Copy Markdown
Contributor Author

Watchdog re-check on 7bacb3d9aa: no review requests a change and the head has not changed since the last status, so nothing is pushed and the branch is not rebased (16 commits behind, below the 25-commit threshold).

AI-assisted: yes

@edubox

edubox commented Oct 31, 2026

Copy link
Copy Markdown
Contributor Author

Watchdog re-check on 7bacb3d9aa against origin/main 474030e584: both points from @oneandonlydean are already in the head, so there is no push and no rebase (16 commits behind, below the 25-commit threshold).

AI-assisted: yes

@edubox

edubox commented Oct 31, 2026

Copy link
Copy Markdown
Contributor Author

Rebased automatically onto current main (ca073ec3ad); head is now 8e89d8959c. Focused tests pass; check_conventions.py --base origin/main and git diff --check are clean.

@edubox
edubox force-pushed the feat/libc-numpunct-wide branch from 7bacb3d to 8e89d89 Compare October 31, 2026 18:03
@edubox

edubox commented Oct 31, 2026

Copy link
Copy Markdown
Contributor Author

Watchdog verification on head 8e89d8959c (no code changes, no rebase; 12 commits behind main 16452da934).

  • ctest --test-dir build -R '^guest_locale$': passes.
  • python3 tools/check_conventions.py --base origin/main and git diff --check: clean.
  • Both points from @oneandonlydean are already in this head: WideNumpunctGrouping uses AssignCString, the test verifies the narrow empty grouping (capacity 15 and a narrow buffer) and the debt paragraph now says grouping is narrow; the local extern for the wide id is gone, and the only declaration is the one in Api.hpp, which LocaleSupport.cpp includes.
  • The write-watch failures are upstream duplicate add_test names in core/libs/tests/write_watch/CMakeLists.txt on main; test(libc): register the macOS write watch fault tests once #13220 fixes them.

Nothing is pushed.

@edubox
edubox force-pushed the feat/libc-numpunct-wide branch from 8e89d89 to 90d4acc Compare November 1, 2026 02:04
@edubox

edubox commented Nov 1, 2026

Copy link
Copy Markdown
Contributor Author

Rebased onto current main 0a148be963 (head 90d4acce8e). The macOS write-watch failures were the duplicate execute-fault/read-fault registrations from main, already fixed on main by 19375d89c4; the rebased tree inherits the single registration and cmake -S core/libs/tests/write_watch configures cleanly here.

@oneandonlydean the two review points stay as in the previous head: grouping is stored and returned through the narrow AssignCString path (test checks the narrow inline representation), and LocaleSupport.cpp includes Api.hpp with no local extern for the id.

  • guest_locale passes (1/1).
  • tools/check_conventions.py --base origin/main: all checks passed.

AI-assisted: yes (opencode).

@uttam12331

Copy link
Copy Markdown

Hi @edubox, #14373 (the numpunct<char> members) touches the same lines of libc/include/Api.hpp and libc/src/LocaleSupport.cpp as this PR. Since this one is older, I stacked #14373 on your two commits and declared Depends on: #11773, so this lands first and nothing changes on your side. I'll rebase #14373 onto main once this merges. Let me know if you'd prefer a different order.

@edubox

edubox commented Nov 1, 2026

Copy link
Copy Markdown
Contributor Author

Rebased automatically onto current main (ba627802e2); head is now 014001a2d0. Focused tests pass; check_conventions.py --base origin/main and git diff --check are clean.

@edubox
edubox force-pushed the feat/libc-numpunct-wide branch from 90d4acc to 014001a Compare November 1, 2026 12:02
@edubox

edubox commented Nov 1, 2026

Copy link
Copy Markdown
Contributor Author

Watchdog verification on the current head 014001a2d0 (already rebased onto main ba627802e2; no further changes or push).

  • Both points from @oneandonlydean are in this head: WideNumpunctGrouping uses the narrow AssignCString path (the test checks the narrow empty grouping: inline capacity 15 and a narrow buffer), and LocaleSupport.cpp has no local extern for the id; Api.hpp is the single declaration.
  • guest_locale rebuilt and passed (1/1).
  • python3 tools/check_conventions.py --base origin/main and git diff --check: clean.
  • The earlier #11504 overlap is resolved (it merged and the head calls GuestLocale::AllocateStringStorage).

AI-assisted: yes

@oneandonlydean
oneandonlydean merged commit 71d6f92 into boykopovar:main Nov 2, 2026
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants