blob: ca34812de9a38c0489bd0c6ef87dd5688a8f3742 [file] [log] [blame] [edit]
// A simple program to reproduce the output of "locale -a" with the
// //third_party/glibc_locale supported locales.
#include <ctype.h>
#include <locale.h>
#include <stdio.h>
#include <string.h>
#include <set>
#include <string>
#include "third_party/glibc_locales/glibc_locales.h"
#include "third_party/glibc_locales/supported_locales.h"
void help() {
printf("We only support 'locale -a'.\n\n");
printf("This program prints a list of locales that are supported by\n");
printf("both the glibc_locales library and the underlying glibc\n");
printf("implementation, in a format matching glibc's locale -a output.\n");
}
int main(int argc, char **argv) {
// Check that we are called as "locale -a". Return a nonzero exit code
// unless we are called as "locale --help".
if ((argc != 2) || strcmp("-a", argv[1])) {
help();
return (argc != 2 || strcmp("--help", argv[1]));
}
// Loop over all locales supported by the glibc_locales library.
std::set<std::string> locales = {UTF_LOCALES, NONUTF_LOCALES, "C", "POSIX"};
for (const std::string &name : locales) {
// Does glibc like this locale? If not, don't print it.
google_locale_t locale = google_newlocale(LC_ALL, name.c_str(), NULL, 1);
if (locale == NULL) continue;
// Normalize any codeset name; e.g. replace "UTF-8" with "utf8".
std::string normalized;
bool in_codeset = false;
for (const char &c : name) {
if (in_codeset) {
if (c == '@')
in_codeset = false;
else if (!isalnum(c))
continue;
normalized.push_back(tolower(c));
} else {
if (c == '.') in_codeset = true;
normalized.push_back(c);
}
}
printf("%s\n", normalized.c_str());
}
}