| // 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()); |
| } |
| } |