31 | | int main(int argc, char **argv) |
| 34 | static const char* kHelpMessage = |
| 35 | "Set system-wide locale\n" |
| 36 | "\n" |
| 37 | "Arguments for long options are mandatory for short options too.\n" |
| 38 | "Arguments for getting help:\n" |
| 39 | " -h, --help Print usage message, this help text and exit\n" |
| 40 | "\n" |
| 41 | "Arguments for listing locales:\n" |
| 42 | " -l, --list Switch to list mode.\n" |
| 43 | " -d, --details List in a long, detailed format:\n" |
| 44 | " code<TAB>language<TAB>country<TAB>script<TAB>variant<TAB>" |
| 45 | "name\n" |
| 46 | "\n" |
| 47 | "Arguments for setting locale:\n" |
| 48 | " -c, --country Specify country for locale\n" |
| 49 | " -s, --script Specify script for locale\n" |
| 50 | " -x, --variant Specify language variant\n" |
| 51 | "\n" |
| 52 | " Please note, that these can be specified using underscores too.\n" |
| 53 | " Example:\n" |
| 54 | " setlocale en_US\n" |
| 55 | " setlocale az_Latn_AZ\n" |
| 56 | " When multiple locales are specified, the seconds gets set as secondary, " |
| 57 | "the third as tertiary, etc.\n" |
| 58 | ; |
| 59 | static const char* kListModeButTrailingArgsMessage = |
| 60 | "Error: List mode specified, but it seems like locales too.\n"; |
| 61 | static const char* kLocaleNotFound = |
| 62 | "Warning: Locale %s not found.\n"; |
| 63 | static const char* kNoCodeSpecifiedMessage = |
| 64 | "Error: No language code specified.\n"; |
| 65 | static const char* kUnknownArgMessage = "Error: Unknown argument: -%c\n"; |
| 66 | static const char* kUsageMessage = |
| 67 | "Usage: setlocale -l|--list [-d|--details]\n" |
| 68 | "or setlocale -h|--help\n" |
| 69 | "or setlocale locale_code[ locale_code[ locale_code ...]] " |
| 70 | "[-c|--country country] [-s|--script script] [-v|--variant variant]\n" |
| 71 | ; |
| 72 | |
| 73 | |
| 74 | void |
| 75 | listLocales(bool detailed = false) |
| 76 | { |
| 77 | // query for all available languages |
| 78 | BMessage languages; |
| 79 | BLocaleRoster::Default()->GetAvailableLanguages(&languages); |
| 80 | |
| 81 | const char* id; |
| 82 | for (int32 i = 0; languages.FindString("language", i, &id) == B_OK; i++) |
| 83 | { |
| 84 | fputs(id, stdout); |
| 85 | if (detailed) { |
| 86 | BLanguage* language; |
| 87 | if (BLocaleRoster::Default()->GetLanguage(id, &language) == B_OK) |
| 88 | { |
| 89 | // extract all the relevant information about the language |
| 90 | const char* code = language->Code(); |
| 91 | const char* country = language->CountryCode(); |
| 92 | const char* script = language->ScriptCode(); |
| 93 | const char* variant = language->Variant(); |
| 94 | BString name; language->GetNativeName(name); |
| 95 | |
| 96 | // print the information |
| 97 | putchar('\t'); |
| 98 | printf("%s\t", code); |
| 99 | printf("%s\t", country); |
| 100 | printf("%s\t", script ? script : ""); |
| 101 | printf("%s\t", variant ? variant : ""); |
| 102 | printf("%s", name.String()); |
| 103 | |
| 104 | delete language; |
| 105 | } else |
| 106 | fprintf(stderr, "Failed to get BLanguage for %s\n", id); |
| 107 | } |
| 108 | putchar('\n'); |
| 109 | } |
| 110 | } |
| 111 | |
| 112 | |
| 113 | int |
| 114 | main(const int argc, char* const argv[]) |
40 | | for (int i = 1; i < argc; ++i) { |
41 | | if (*argv[i] == '-') { |
42 | | // parse a command line flag |
43 | | if (!strcmp(argv[i], "--list")) |
44 | | list = true; |
45 | | else if (argv[i][1] && !argv[i][2]) { |
46 | | // found a single character flag |
47 | | if (argv[i][1] == 'l') |
48 | | list = true; |
49 | | else if (argv[i][1] == 's') |
50 | | queryScript = argv[++i]; |
51 | | else if (argv[i][1] == 'v') |
52 | | queryVariant = argv[++i]; |
53 | | else { |
54 | | err = true; |
| 123 | { |
| 124 | static const struct option longopts[] = { |
| 125 | { "help", no_argument, NULL, 'h' }, |
| 126 | { "list", no_argument, NULL, 'l' }, |
| 127 | { "details", no_argument, NULL, 'd' }, |
| 128 | { "country", required_argument, NULL, 'c' }, |
| 129 | { "script", required_argument, NULL, 's' }, |
| 130 | { "variant", required_argument, NULL, 'x' }, |
| 131 | }; |
| 132 | const char* optstring = "hldc:s:x:"; |
| 133 | |
| 134 | for (int c = getopt_long(argc, argv, optstring, longopts, NULL); |
| 135 | c != -1; c = getopt_long(argc, argv, optstring, longopts, NULL)) |
| 136 | { |
| 137 | switch (c) |
| 138 | { |
| 139 | case 'h': |
| 140 | fputs(kUsageMessage, stdout); |
| 141 | fputs(kHelpMessage, stdout); |
| 142 | return 0; |
| 143 | |
| 144 | case 'l': |
| 145 | queryList = true; |
84 | | const char* id; |
85 | | for (int32 i = 0; languages.FindString("language", i, &id) == B_OK; ++i) { |
86 | | BLanguage* language; |
87 | | if (BLocaleRoster::Default()->GetLanguage(id, &language) == B_OK) { |
88 | | // extract all the relevant information about the language |
89 | | BString name; |
90 | | language->GetNativeName(name); |
91 | | const char* code = language->Code(); |
92 | | const char* country = language->CountryCode(); |
93 | | const char* script = language->ScriptCode(); |
94 | | const char* variant = language->Variant(); |
95 | | |
96 | | // if we're listing, print the information |
97 | | if (list) |
98 | | printf("%s\t%s\t%s\t%s\t%s\n", |
99 | | code, |
100 | | country ? country : "", |
101 | | script ? script : "", |
102 | | variant ? variant : "", |
103 | | name.String()); |
104 | | else if (!strcasecmp(code, queryCode) |
105 | | && matches(country, queryCountry) |
106 | | && matches(script, queryScript) |
107 | | && matches(variant, queryVariant)) { |
108 | | // found a match! set the new locale |
| 195 | // And do the job |
| 196 | { |
110 | | preferred.AddString("language", id); |
| 198 | for (int i = optind; i < argc; i++) |
| 199 | { |
| 200 | BString targetCode(argv[i]); |
| 201 | |
| 202 | if (queryCountry != NULL) |
| 203 | targetCode += BString(queryCountry).Prepend('_', 1); |
| 204 | |
| 205 | if (queryVariant != NULL) |
| 206 | targetCode += BString(queryVariant).Prepend('_', 1); |
| 207 | |
| 208 | if (queryScript != NULL) |
| 209 | targetCode += BString(queryScript).Prepend('_', 1); |
| 210 | |
| 211 | { |
| 212 | BLanguage* language; |
| 213 | if (BLocaleRoster::Default()->GetLanguage( |
| 214 | targetCode.String(), &language) == B_OK) { |
| 215 | // found a match! set the new locale |
| 216 | preferred.AddString("language", |
| 217 | targetCode.String()); |
| 218 | } else { |
| 219 | fprintf(stderr, kLocaleNotFound, |
| 220 | targetCode.String()); |
| 221 | } |
| 222 | } |
| 223 | } |