@@ -124,36 +124,39 @@ ngettext <- function(n, msg1, msg2, domain = NULL)
124124gettextf <- function (fmt , ... , domain = NULL , trim = TRUE )
125125 sprintf(gettext(fmt , domain = domain , trim = trim ), ... )
126126
127- # # Could think of using *several* domains, i.e. domain = vector; but seems complicated;
128- # # the default domain="R" seems to work for all of base R: {"R", "R-base", "RGui"}
129- Sys.setLanguage <- function (lang , unset = " en" , force = FALSE )
127+ Sys.setLanguage <- function (lang , unset = " en" ) # , force = FALSE
130128{
131129 stopifnot(is.character(lang ), length(lang ) == 1L , # e.g., "es" , "fr_CA"
132130 lang == " C" || grepl(" ^[a-z][a-z]" , lang ))
133131 curLang <- Sys.getenv(" LANGUAGE" , unset = NA ) # so it can be reset
134132 if (is.na(curLang ) || ! nzchar(curLang ))
135133 curLang <- unset # "factory" default
136134 if (! capabilities(" NLS" ) || is.na(.popath )) {
137- warning(" no natural language support or missing translations" )
135+ warning(" no natural language support or missing translations" ,
136+ domain = NA )
138137 return (invisible (structure(curLang , ok = FALSE )))
139138 }
140- if (identical(" C" , Sys.getlocale()) && lang != " C" ) { # # e.g. LC_ALL=C R on Linux
141- if (force ) {
142- lcSet <- if (.Platform [[" OS.type" ]] == " unix" ) # works to "undo LC_ALL=C"
143- paste0(collapse = " " , vapply(c(" LC_ALL" , " LC_MESSAGES" ),
144- \(a ) Sys.setlocale(a , " en_US.UTF-8" ), " " ))
145- # # TODOs: 1) we assume en_US.UTF-8 exists on all "unix"
146- # # 2) How to deal w/ Windows ? {can set things but with *no* effect}
147- ok.lc <- ! is.null(lcSet ) && nzchar(lcSet ) # NULL or "" are not ok
148- if (! ok.lc )
149- warning(gettextf(
150- " In bare C locale: LANGUAGE reset, but message language may be unchanged" ),
151- domain = NA )
152- } else { # !force (default) :
153- warning(gettextf(" In bare C locale, not forcing locale; possibly use 'force = TRUE'?" ),
154- domain = NA )
155- return (invisible (structure(curLang , ok = FALSE )))
156- }
139+ if (Sys.getlocale(" LC_CTYPE" ) %in% c(" C" , " POSIX" ) && # e.g. LC_ALL=C
140+ lang != " C" ) {
141+ # # POSIX 1003.1-2024 specifies that LANGUAGE shall not override
142+ # # a C locale (GNU gettext also ignores LANGUAGE in C.UTF-8),
143+ # # and Sys.setLanguage() shouldn't try that either (by default).
144+ # # Most languages need non-ASCII characters, but those would get
145+ # # displayed as ? or * (or worse) in a C locale and attempts to
146+ # # change the session charset are known to be fragile.
147+ # if(force) {
148+ # lcSet <- if(.Platform[["OS.type"]] == "unix") # works to "undo LC_ALL=C"
149+ # paste0(collapse="", vapply(c("LC_ALL", "LC_MESSAGES"),
150+ # \(a) Sys.setlocale(a, "en_US.UTF-8"), ""))
151+ # ## TODOs: 1) we assume en_US.UTF-8 exists on all "unix"
152+ # ## 2) How to deal w/ Windows ? {can set things but with *no* effect}
153+ # ok.lc <- !is.null(lcSet) && nzchar(lcSet) # NULL or "" are not ok
154+ # if(!ok.lc)
155+ # warning("in a C locale: LANGUAGE reset, but message language may be unchanged")
156+ # } else { # !force (default) :
157+ warning(" in a C locale: cannot set language" , domain = NA )
158+ return (invisible (structure(curLang , ok = FALSE )))
159+ # }
157160 } else ok.lc <- TRUE
158161 ok <- Sys.setenv(LANGUAGE = lang )
159162 if (! ok )
0 commit comments