Follow-up to Swiplserver: load existing prolog file into server - #3 by jan - splitting it into its own thread, because my reply is long and not really related to swiplserver.
Inside Terminal.app, at least some locale variables should be set. There is a setting to disable this (Terminal > Preferences…, Profiles > Advanced > Set locale environment variables on startup), but I think it’s enabled by default. So the average terminal should have locale information, unless you go out of your way to disable it.
With the setting enabled, you should get something like LANG=de_DE.UTF-8
. The language part comes from the system language/region settings, and the encoding part comes from the Terminal.app settings. You can choose a different encoding right above where you can disable the locale variables, but I don’t know why you’d use anything other than the default UTF-8.
Interestingly, if I change my system language (no matter which) and then restart Terminal.app, it sets a different variable - LANG
becomes unset, and instead it just sets LC_CTYPE=UTF-8
. If I switch back to German, it sets LANG=de_DE.UTF-8
again. I’m not sure why it does this, but my guess is that it’s because I changed the language in a running system, and that it would set LANG=en_US.UTF-8
once I relog/restart.
In any case, the variables are set by Terminal.app itself, not by any shell profile. You can see this if you ask Terminal.app to run printenv
without a shell (Shell > New Command…) - LANG
/LC_CTYPE
is still set. But you are correct that they are only set inside Terminal.app, not in a regular macOS GUI application. If you run printenv
from SWI-Prolog.app, no locale variables are set:
?- use_module(library(process)).
?- process_create(path(printenv), [], [stdout(pipe(_Stdout))]), read_stream_to_codes(_Stdout, _Codes), string_codes(String, _Codes).
I don’t know if there’s any way to make macOS set locale variables inside GUI applications. My guess is that there isn’t, and that they expect you to use the native macOS locale and encoding handling APIs instead, like CFString
and CFLocale
(and their Objective-C/Swift counterparts).
However, it seems that macOS tries to avoid the concept of a “default encoding”. The closest thing is CFStringGetSystemEncoding
, but the documentation warns that it’s only meant for working with legacy Mac OS APIs that don’t use Unicode, and that your application code should use a different encoding. And indeed, on my system, this function returns kCFStringEncodingMacRoman
, which was the system encoding of German Classic Mac OS, but is basically never used on modern macOS.
So I don’t think it makes much sense to try to determine a “system text encoding” on macOS, at least not outside of a terminal where you have Unix-style locale info. I wonder if SWI on macOS should simply default to utf8
, as that is the de facto standard (on macOS and elsewhere). At the moment, it defaults to text
and behaves like Latin-1, which is basically never the right choice on macOS.