A página man para setlocale
parece dizer que o código do idioma e o nome da codificação de caracteres são suficientes para definir a localidade apropriada:
Um nome de localidade geralmente tem o formato language[_territory][.codeset][@modifier], em que language é um código de idioma ISO 639, território é um código de país ISO 3166 e codeset é um conjunto de caracteres ou identificador de codificação como ISO- 8859-1 ou UTF-8.
No entanto, um teste rápido mostra que apenas a parte "modificadora" de um nome de localidade é opcional:
void tryLocale(const char * locid)
{
char * result = std::setlocale(LC_CTYPE, locid);
std::cout << locid << " = " << (result ? result : "fail") << std::endl;
}
int main()
{
tryLocale("de"); // de = fail
tryLocale("de_DE"); // de_DE = fail
tryLocale("de_DE.CP1252"); // de_DE.CP1252 = de_DE.CP1252
tryLocale("de.CP1252"); // de.CP1252 = fail
tryLocale(".CP1252"); // .CP1252 = fail
}
Meu problema é que eu só sei o nome da codificação desejada (por exemplo ISO-8859-1
, ) e posso criar o código do idioma (por exemplo, en
). Não tenho ideia de como encontrar um nome de país apropriado (por exemplo US
, ), e não estou interessado em um país de qualquer maneira: só quero que funções como tolower
no meu aplicativo usem a página de código correta.
Acho que você vai ter que passar por eles. Em
zsh
:Ou o mesmo usando seu
$langinfo
array associativo especial nozsh/langinfo
módulo:Listaria todas as localidades disponíveis que usam ISO-8859-1 como charmap.
Mas observe que a categoria em que
LC_CTYPE
o charmap / codeset é especificado também abrange a classificação de caracteres: o que é uma letra minúscula, o que é pontuação etc.tolower()
o próximo, mesmo se o mesmo conjunto de códigos for usado.Por exemplo, veja como as letras minúsculas
I
estãoı
nas localidades turcas do GNU, independentemente de qual charmap está sendo usado (UTF-8, ISO-8859-9...), enquantoi
na maioria das outras localidades que também usam UTF-8.Você pode dar uma olhada nas definições de origem de localidade, por exemplo com:
Em um sistema GNU para ver as diferenças entre localidades para a
LC_CTYPE
categoria. Você não encontrará o charmap lá, as localidades para combinações desses arquivos e os charmaps são gerados usandolocaledef -i thosefiles -f charmap
, embora apenas algumas combinações façam sentido, veja/usr/share/i18n/SUPPORTED
a lista.Por exemplo, a
en_GB
localidade em seu sistema pode ter sido gerada comlocaledef -i locales/en_GB -f charmaps/ISO-8859-1.gz
een_GB.UTF-8
aquela comlocaledef -i locales/en_GB -f charmaps/UTF-8.gz
.Então aqui, talvez você precise encontrar uma localidade que use
ISO-8859-1
como charmap, mas também com regras de transliteração e classificações de caracteres que façam sentido na Grã-Bretanha continental para o inglês britânico ou para falantes de alemão na Itália / Alemanha etc, como por exemplo que satisfaçam:O que deve restringir um pouco a escolha.
Observe que
language
eterritory
são extensões GNU não padrão, o que explica por que você não as encontrará nos arquivos$langinfo
. A documentação da GNU libc (info libc langinfo
) menciona apenas:/usr/include/langinfo.h
no meu sistema tem:Veja também
locale -k LC_IDENTIFICATION
,locale -k LC_CTYPE
para a lista de palavras-chave suportadas para uma determinada categoria de localidade em sistemas GNU (locale -kc LC_ALL
costumava funcionar, mas aparentemente não funciona mais hoje em dia).