Skip to content

bugfix(string): Keep %hs printable when rewriting wide formats for libc - #5

Open
githubawn wants to merge 523 commits into
bobtista:bobtista/topic/trunkfrom
githubawn:fix/wide-format-hs
Open

bugfix(string): Keep %hs printable when rewriting wide formats for libc#5
githubawn wants to merge 523 commits into
bobtista:bobtista/topic/trunkfrom
githubawn:fix/wide-format-hs

Conversation

@githubawn

Copy link
Copy Markdown

translateWideFormat emitted length modifiers as it read them, so an h on s/c was passed straight through to the platform vswprintf.

MSVC spells a narrow argument %hs/%hc. musl rejects that outright: vswprintf returns -1 and the whole formatted string comes out empty.

Why it kills startup

GameText formats its missing-label placeholder as MISSING: '%hs'. So any INI naming a label the string table lacks fetches an empty string, and INI::parseAndTranslateLabel throws on it — taking the engine down during startup rather than showing the placeholder.

This is reachable with untouched retail data: CommandMap.ini asks for GUI:SaveView5, which generals.csf does not define.

Fix

Hold the length modifiers back until the conversion character is known, then decide:

  • %hs / %hc mean narrow, which is exactly what a bare %s/%c already means to libc, so the modifier is dropped
  • anything else wide keeps its l
  • modifiers on other conversions (%hd, %zu) still pass through untouched

Platform impact

Windows keeps its own vswprintf path and is untouched — translateWideFormat is only compiled off Windows.

bobtista added 30 commits July 30, 2026 22:35
… on Windows

(cherry picked from commit 3704ae283516a47b27d4a5511566d4f8f6169a7c)
(cherry picked from commit c2e4ebd508ef4ebdaa1bdc1ac513632dce0bf5a6)
…n-Windows builds

(cherry picked from commit bc2a0e474438860d80addcbf6e1795624624ecd9)
(cherry picked from commit 79c1e3c42fb96fa060f78720ed80ab3f424162a4)
…destroyed

(cherry picked from commit 757b56e262097d43b3dbba912e1026fef11a6efe)
(cherry picked from commit 5e6c40439b05766d872e32e4a3f5b780bd92f7ab)
…pling can't read out of bounds and crash

(cherry picked from commit bcf96610c984fde5d1bd614cb94569c06ba13db6)
(cherry picked from commit d3f978645a3a89cb747220d6aa9f58631b0e87e6)
…ady on construction complete (non-retail CRC)

(cherry picked from commit 323a3c220da03d8e7b7c636a5fc049d6f9715f9b)
(cherry picked from commit dbee96e4b2aeb170ff4f89a9d64af98881ecae7a)
…erals Challenge so the next general isn't instantly defeated

(cherry picked from commit 255fc6bacfa2db0a346b87f550f0dffff8889237)
(cherry picked from commit 053938d17936b1cba41436c658a0bf38f5467ba5)
…e Continue starts the next battle instead of an instant defeat

(cherry picked from commit ba12ef4621e95d7719c542f17388802532f40ba1)
(cherry picked from commit 09110dd45e6b4dcfcac75b5334de6d7fe9a6866d)
…int so debug builds link

(cherry picked from commit a3d78a591598b5abadd60470de79d4077e42e252)
(cherry picked from commit 60e92e4fa5dc9559f87ecdb9a5b4c6bada19ae42)
…_ZOOM hack, deferring camera height limits to GameData.ini

(cherry picked from commit a2625f8ee57fb8c9955a8f5a52444f7f1d4dd1b2)
(cherry picked from commit 79fe3af9c0bfe5e6bf8d0302678b414251b05333)
(cherry picked from commit 6aca92fca0d16b65a30b76ced3d0cc40e2d528ee)
(cherry picked from commit 8b5dceefe4b42fc9c7c1420565efaa5d1170337c)
bobtista and others added 26 commits July 30, 2026 22:37
translateWideFormat emitted length modifiers as it read them, so an 'h' on
s/c was passed straight through. MSVC spells a narrow argument %hs/%hc, but
musl rejects that outright: vswprintf returns -1 and the whole string comes
out empty.

GameText formats its missing-label placeholder that way ("MISSING: '%hs'"),
so any INI naming a label the string table lacks fetched an empty string and
INI::parseAndTranslateLabel threw, killing the engine during startup. Retail
CommandMap.ini asks for GUI:SaveView5, which generals.csf does not define.

Hold the modifiers back until the conversion character is known. %hs/%hc mean
narrow, which is what a bare %s/%c already means to libc, so the modifier is
dropped there; anything else wide keeps its 'l'. Modifiers on other
conversions (%hd, %zu) still pass through untouched.

Windows keeps its own vswprintf path and is untouched.
@bobtista
bobtista force-pushed the bobtista/topic/trunk branch 4 times, most recently from 66cf60b to 0f1e948 Compare August 3, 2026 19:03
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.

2 participants