Remix.run Logo
kevin_thibedeau 2 days ago

Everybody in gettext land uses (s)printf format specifiers. Nobody thought to do that at MS?

Arnavion 2 days ago | parent | next [-]

The ShowError() API they're talking about doesn't take a format string. It takes a resource ID which is an integer that's essentially an index in the resource table. So running the message compiler produces a C header that defines ERROR_BITLOCKER_PASSPHRASE_MINIMUM_TOO_LONG to an integer constant, and then ShowError(ERROR_BITLOCKER_PASSPHRASE_MINIMUM_TOO_LONG) looks up the string at that index in the resource table and displays it.

https://learn.microsoft.com/en-us/windows/win32/eventlog/mes...

(You'll note that that page mentions that FormatMessage() does support printf-style format specifiers in the string resource. That's why I'm saying that their ShowError() specifically is the one that doesn't.)

JdeBP 2 days ago | parent | prev | next [-]

I'd say that of course people at Microsoft thought to do this, twenty years prior at the time of OS/2 1.0 …

… except that it might have been people from IBM. OS/2 had a DosGetMessage() API function that looked up messages in a compiled message file and inserted strings taken from an application-supplied array wherever a %1 to a %9 occurred in the message.

It was regularly used to edit the applicable filename, drive letter, numeric values, or whatnot into error messages.

m0llusk 2 days ago | parent | prev | next [-]

In a way this is more like Perl's maketext or maybe Mozilla Fluent. Reasonable translations need to be constructed using variable inputs and correct messages can vary greatly between languages with grammar agreement and such. While gettext does have some extra support for getting numeric translations and agreements right it is kind of hacked in as an add on to a text lookup procedure rather than in terms of constructing the messages based on inputs.

arcfour 2 days ago | parent | prev [-]

The Microsoft way is to do things backwards, make the possible impossible, and wrap simple, well-understood APIs behind 16 layers of abstraction with awful names that will ever so slightly munge your arguments. Surely you know this :-)