Skip to content

Conversation

@MarekKnapek
Copy link
Contributor

Every Windows API interaction is wrapped with UTF-8 -> UTF-16 conversion. Meaning both nob and nob user code can stay UTF-8. Also every result from Windows API is wrapped with UTF-16 -> UTF-8 conversion.

If nob user wishes to use printf-style output, they need to use nob_log instead. Or detect Windows and do the conversion themselves (I'm not changing nob public API, and printf is not part of nob API).

@KillerxDBr
Copy link
Contributor

I recommend changing those for the correct ones, as i explained at #202 (comment) to avoid any problem if we ever use something from those headers in the future

#    define _WINUSER_ // -> NOUSER
#    define _WINGDI_  // -> NOGDI
#    define _IMM_     // -> NOIME
#    define _WINCON_  // -> NOAPISET i believe, but need to #include <stringapiset.h> manually

@vylsaz
Copy link
Contributor

vylsaz commented Jan 28, 2026

I feel that using the wide variant for file api is necessary (for longer names), but libc console output functions should be fine with SetConsoleOutputCP(CP_UTF8)?

@rexim
Copy link
Member

rexim commented Jan 30, 2026

I feel that using the wide variant for file api is necessary (for longer names), but libc console output functions should be fine with SetConsoleOutputCP(CP_UTF8)?

I agree. Can we do this instead of all that nob__*printf disaster? Sounds like a good way to cut down on the changes.

@MarekKnapek
Copy link
Contributor Author

# define _WINUSER_ // -> NOUSER
...
# include <Windows.h>

Should be in separate change set.

SetConsoleOutputCP(CP_UTF8)

How should I do this? Currently, nob.h does not have any global init+deinit functions. Call to SetConsoleOutputCP is needed only once somewhere at the start of a program. Maybe it should be done by each nob user separately, but this does not seem much ergonomic. Currently, there is no way to automagically execute some code at program startup (excluding GCC extensions).

Next. This changes global state. Meaning state that remains after program exit. The console lives after program execution ends, affecting any and all other programs executed after nob-style build. These programs might not appreciate changing the defaults behind their back.

that nob__*printf disaster

Yes, it is disaster. But printf-style functions are state-less. We need something with state. Either changing the state just before each printf call and back right away. That is what I did in my PR. I introduced new API, that was bad. Now I introduced ugly conditional macros instead.

Or, changing the state once at program startup, and changing it back just before program exit. But. nob-style program lacks some global init function or functionality. Therefore I suggest adding a new API in form of nob_init and nob_deinit or something similar that each nob user would need to call before any other code. This would change the global code-page on Windows. (The nob_deinit could be called form at_exit handler, no need for nob user to call it explicitly.)

Because I have no idea where to call the SetConsoleOutputCP function, and where to revert its effects back.

@vylsaz
Copy link
Contributor

vylsaz commented Jan 31, 2026

The user can change the log handler themselves, I think it's more flexible that way

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.

4 participants