2010-02-17 23:01:56 +08:00
|
|
|
/*
|
2013-04-23 17:44:36 +08:00
|
|
|
* Copyright (c) 2010, 2011, 2012, 2013 Corinna Vinschen
|
2010-02-17 23:01:56 +08:00
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
|
|
* SUCH DAMAGE.
|
|
|
|
*/
|
2011-10-10 22:57:48 +08:00
|
|
|
#include <errno.h>
|
2010-02-17 23:01:56 +08:00
|
|
|
#include <stdio.h>
|
2012-07-06 22:52:33 +08:00
|
|
|
#include <stdlib.h>
|
2010-02-23 22:07:08 +08:00
|
|
|
#include <ctype.h>
|
2010-02-17 23:01:56 +08:00
|
|
|
#include <getopt.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <wchar.h>
|
2023-02-23 07:22:56 +08:00
|
|
|
#include <wctype.h>
|
2010-02-17 23:01:56 +08:00
|
|
|
#include <locale.h>
|
|
|
|
#include <langinfo.h>
|
|
|
|
#include <limits.h>
|
2010-02-23 22:07:08 +08:00
|
|
|
#include <sys/cygwin.h>
|
2011-10-10 17:50:43 +08:00
|
|
|
#include <cygwin/version.h>
|
2010-02-17 23:01:56 +08:00
|
|
|
#include <windows.h>
|
|
|
|
|
2010-02-23 22:07:08 +08:00
|
|
|
#define LOCALE_ALIAS "/usr/share/locale/locale.alias"
|
|
|
|
#define LOCALE_ALIAS_LINE_LEN 255
|
|
|
|
|
2020-08-07 19:29:43 +08:00
|
|
|
static void __attribute__ ((__noreturn__))
|
2011-10-10 17:50:43 +08:00
|
|
|
usage ()
|
|
|
|
{
|
|
|
|
printf (
|
|
|
|
"Usage: %1$s [-amvhV]\n"
|
|
|
|
" or: %1$s [-ck] NAME\n"
|
2016-08-17 16:58:04 +08:00
|
|
|
" or: %1$s [-iusfnU]\n"
|
2011-10-10 22:57:48 +08:00
|
|
|
"\n"
|
2011-10-10 17:50:43 +08:00
|
|
|
"Get locale-specific information.\n"
|
|
|
|
"\n"
|
|
|
|
"System information:\n"
|
|
|
|
"\n"
|
|
|
|
" -a, --all-locales List all available supported locales\n"
|
|
|
|
" -m, --charmaps List all available character maps\n"
|
|
|
|
" -v, --verbose More verbose output\n"
|
|
|
|
"\n"
|
|
|
|
"Modify output format:\n"
|
|
|
|
"\n"
|
|
|
|
" -c, --category-name List information about given category NAME\n"
|
|
|
|
" -k, --keyword-name Print information about given keyword NAME\n"
|
|
|
|
"\n"
|
|
|
|
"Default locale information:\n"
|
|
|
|
"\n"
|
2016-08-17 16:58:04 +08:00
|
|
|
" -i, --input Print current input locale\n"
|
2011-10-10 17:50:43 +08:00
|
|
|
" -u, --user Print locale of user's default UI language\n"
|
|
|
|
" -s, --system Print locale of system default UI language\n"
|
|
|
|
" -f, --format Print locale of user's regional format settings\n"
|
|
|
|
" (time, numeric & monetary)\n"
|
|
|
|
" -n, --no-unicode Print system default locale for non-Unicode programs\n"
|
|
|
|
" -U, --utf Attach \".UTF-8\" to the result\n"
|
|
|
|
"\n"
|
|
|
|
"Other options:\n"
|
|
|
|
"\n"
|
|
|
|
" -h, --help This text\n"
|
|
|
|
" -V, --version Print program version and exit\n\n",
|
2011-10-10 22:57:48 +08:00
|
|
|
program_invocation_short_name);
|
2020-08-07 19:29:43 +08:00
|
|
|
exit (0);
|
2011-10-10 17:50:43 +08:00
|
|
|
}
|
2010-02-17 23:01:56 +08:00
|
|
|
|
|
|
|
void
|
2011-10-10 17:50:43 +08:00
|
|
|
print_version ()
|
2010-02-17 23:01:56 +08:00
|
|
|
{
|
2016-05-24 17:16:39 +08:00
|
|
|
printf ("locale (cygwin) %d.%d.%d\n",
|
2011-10-10 17:50:43 +08:00
|
|
|
CYGWIN_VERSION_DLL_MAJOR / 1000,
|
|
|
|
CYGWIN_VERSION_DLL_MAJOR % 1000,
|
2016-05-24 17:16:39 +08:00
|
|
|
CYGWIN_VERSION_DLL_MINOR);
|
2010-02-17 23:01:56 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
struct option longopts[] = {
|
|
|
|
{"all-locales", no_argument, NULL, 'a'},
|
|
|
|
{"category-name", no_argument, NULL, 'c'},
|
2011-10-10 17:50:43 +08:00
|
|
|
{"format", no_argument, NULL, 'f'},
|
|
|
|
{"help", no_argument, NULL, 'h'},
|
2016-08-17 16:58:04 +08:00
|
|
|
{"input", no_argument, NULL, 'i'},
|
2010-02-17 23:01:56 +08:00
|
|
|
{"keyword-name", no_argument, NULL, 'k'},
|
|
|
|
{"charmaps", no_argument, NULL, 'm'},
|
2011-10-10 17:50:43 +08:00
|
|
|
{"no-unicode", no_argument, NULL, 'n'},
|
2010-02-17 23:01:56 +08:00
|
|
|
{"system", no_argument, NULL, 's'},
|
|
|
|
{"user", no_argument, NULL, 'u'},
|
|
|
|
{"utf", no_argument, NULL, 'U'},
|
|
|
|
{"verbose", no_argument, NULL, 'v'},
|
2011-10-10 17:50:43 +08:00
|
|
|
{"version", no_argument, NULL, 'V'},
|
2010-02-17 23:01:56 +08:00
|
|
|
{0, no_argument, NULL, 0}
|
|
|
|
};
|
2016-08-17 16:58:04 +08:00
|
|
|
const char *opts = "acfhikmnsuUvV";
|
2010-02-17 23:01:56 +08:00
|
|
|
|
|
|
|
int
|
2023-02-23 07:22:56 +08:00
|
|
|
getlocale (PWCHAR loc_name, wchar_t *iso639, wchar_t *iso3166,
|
|
|
|
wchar_t *iso15924 = NULL)
|
2010-02-17 23:01:56 +08:00
|
|
|
{
|
2023-02-23 07:22:56 +08:00
|
|
|
wchar_t *cp;
|
2010-02-17 23:01:56 +08:00
|
|
|
|
2023-02-23 07:22:56 +08:00
|
|
|
/* Skip language-only locales, e. g. "en" */
|
|
|
|
if (!(cp = wcschr (loc_name, L'-')))
|
2010-02-17 23:01:56 +08:00
|
|
|
return 0;
|
2023-02-23 07:22:56 +08:00
|
|
|
++cp;
|
|
|
|
/* Script inside? Scripts are Upper/Lower, e. g. "Latn" */
|
|
|
|
if (iswupper (cp[0]) && iswlower (cp[1]))
|
|
|
|
{
|
|
|
|
wchar_t *cp2;
|
|
|
|
|
|
|
|
/* Skip language-Script locales, missing country */
|
|
|
|
if (!(cp2 = wcschr (cp + 2, L'-')))
|
|
|
|
return 0;
|
|
|
|
/* Otherwise, store in iso15924 */
|
|
|
|
if (iso15924)
|
|
|
|
wcpcpy (wcpncpy (iso15924, cp, cp2 - cp), L";");
|
|
|
|
}
|
|
|
|
cp = wcsrchr (loc_name, L'-');
|
|
|
|
if (cp)
|
|
|
|
{
|
|
|
|
/* Skip numeric iso3166 country name. */
|
|
|
|
if (iswdigit (cp[1]))
|
|
|
|
return 0;
|
|
|
|
/* Special case postfix after iso3166 country name: ca-ES-valencia.
|
|
|
|
Use the postfix thingy as script so it will become a @modifier */
|
|
|
|
if (iswlower (cp[1]))
|
|
|
|
wcpcpy (iso15924, cp + 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!GetLocaleInfoEx (loc_name, LOCALE_SISO639LANGNAME, iso639, 10))
|
|
|
|
return 0;
|
|
|
|
GetLocaleInfoEx (loc_name, LOCALE_SISO3166CTRYNAME, iso3166, 10);
|
2010-02-17 23:01:56 +08:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2010-02-23 22:07:08 +08:00
|
|
|
typedef struct {
|
|
|
|
const char *name;
|
|
|
|
const wchar_t *language;
|
|
|
|
const wchar_t *territory;
|
|
|
|
const char *codeset;
|
|
|
|
bool alias;
|
|
|
|
} loc_t;
|
|
|
|
loc_t *locale;
|
|
|
|
size_t loc_max;
|
|
|
|
size_t loc_num;
|
|
|
|
|
2010-02-17 23:01:56 +08:00
|
|
|
void
|
2010-03-24 05:01:01 +08:00
|
|
|
print_locale_with_codeset (int verbose, loc_t *locale, bool utf8,
|
|
|
|
const char *modifier)
|
2010-02-17 23:01:56 +08:00
|
|
|
{
|
2010-02-23 22:07:08 +08:00
|
|
|
static const char *sysroot;
|
|
|
|
char locname[32];
|
|
|
|
|
|
|
|
if (verbose
|
|
|
|
&& (!strcmp (locale->name, "C") || !strcmp (locale->name, "POSIX")))
|
|
|
|
return;
|
|
|
|
if (!sysroot)
|
|
|
|
{
|
2011-11-29 01:58:48 +08:00
|
|
|
WCHAR sysbuf[PATH_MAX];
|
2010-08-28 19:22:37 +08:00
|
|
|
HMODULE k32 = GetModuleHandleW (L"kernel32.dll");
|
2011-11-29 01:58:48 +08:00
|
|
|
if (GetModuleFileNameW (k32, sysbuf, PATH_MAX))
|
|
|
|
sysroot = (const char *) cygwin_create_path (CCP_WIN_W_TO_POSIX,
|
2010-08-28 19:22:37 +08:00
|
|
|
sysbuf);
|
2010-02-23 22:07:08 +08:00
|
|
|
if (!sysroot)
|
2023-02-23 07:22:56 +08:00
|
|
|
sysroot = "kernel32.dll";
|
2010-02-23 22:07:08 +08:00
|
|
|
}
|
2010-03-24 05:01:01 +08:00
|
|
|
snprintf (locname, 32, "%s%s%s%s", locale->name, utf8 ? ".utf8" : "",
|
|
|
|
modifier ? "@" : "", modifier ?: "");
|
2010-02-23 22:07:08 +08:00
|
|
|
if (verbose)
|
|
|
|
fputs ("locale: ", stdout);
|
2010-02-17 23:01:56 +08:00
|
|
|
if (verbose)
|
2010-02-23 22:07:08 +08:00
|
|
|
{
|
2011-05-03 18:34:25 +08:00
|
|
|
printf ("%-15s ", locname);
|
2010-02-23 22:07:08 +08:00
|
|
|
printf ("archive: %s\n",
|
|
|
|
locale->alias ? LOCALE_ALIAS : sysroot);
|
|
|
|
puts ("-------------------------------------------------------------------------------");
|
|
|
|
printf (" language | %ls\n", locale->language);
|
|
|
|
printf ("territory | %ls\n", locale->territory);
|
2011-05-03 18:34:25 +08:00
|
|
|
printf (" codeset | %s\n\n", utf8 ? "UTF-8" : locale->codeset);
|
2010-02-23 22:07:08 +08:00
|
|
|
}
|
2011-05-03 18:34:25 +08:00
|
|
|
else
|
|
|
|
printf ("%s\n", locname);
|
2010-02-23 22:07:08 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
print_locale (int verbose, loc_t *locale)
|
|
|
|
{
|
2010-03-24 05:01:01 +08:00
|
|
|
print_locale_with_codeset (verbose, locale, false, NULL);
|
2010-02-23 22:07:08 +08:00
|
|
|
char *modifier = strchr (locale->name, '@');
|
|
|
|
if (!locale->alias)
|
|
|
|
{
|
|
|
|
if (!modifier)
|
2010-03-24 05:01:01 +08:00
|
|
|
print_locale_with_codeset (verbose, locale, true, NULL);
|
2023-02-23 07:22:56 +08:00
|
|
|
else if (strcmp (modifier, "@euro"))
|
2010-02-23 22:07:08 +08:00
|
|
|
{
|
|
|
|
*modifier++ = '\0';
|
2010-03-24 05:01:01 +08:00
|
|
|
print_locale_with_codeset (verbose, locale, true, modifier);
|
2010-02-23 22:07:08 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
compare_locales (const void *a, const void *b)
|
|
|
|
{
|
|
|
|
const loc_t *la = (const loc_t *) a;
|
|
|
|
const loc_t *lb = (const loc_t *) b;
|
|
|
|
return strcmp (la->name, lb->name);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
add_locale (const char *name, const wchar_t *language, const wchar_t *territory,
|
|
|
|
bool alias = false)
|
|
|
|
{
|
|
|
|
char orig_locale[32];
|
|
|
|
|
|
|
|
if (loc_num >= loc_max)
|
|
|
|
{
|
|
|
|
loc_t *tmp = (loc_t *) realloc (locale, (loc_max + 32) * sizeof (loc_t));
|
|
|
|
if (!tmp)
|
2023-02-23 07:22:56 +08:00
|
|
|
{
|
2010-02-23 22:07:08 +08:00
|
|
|
fprintf (stderr, "Out of memory!\n");
|
|
|
|
exit (1);
|
|
|
|
}
|
|
|
|
locale = tmp;
|
|
|
|
loc_max += 32;
|
|
|
|
}
|
|
|
|
locale[loc_num].name = strdup (name);
|
|
|
|
locale[loc_num].language = wcsdup (language);
|
|
|
|
locale[loc_num].territory = wcsdup (territory);
|
|
|
|
strcpy (orig_locale, setlocale (LC_CTYPE, NULL));
|
|
|
|
setlocale (LC_CTYPE, name);
|
|
|
|
locale[loc_num].codeset = strdup (nl_langinfo (CODESET));
|
|
|
|
setlocale (LC_CTYPE, orig_locale);
|
|
|
|
locale[loc_num].alias = alias;
|
|
|
|
++loc_num;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
add_locale_alias_locales ()
|
|
|
|
{
|
|
|
|
char alias_buf[LOCALE_ALIAS_LINE_LEN + 1], *c;
|
|
|
|
const char *alias, *replace;
|
|
|
|
char orig_locale[32];
|
|
|
|
loc_t search, *loc;
|
2010-03-24 05:26:03 +08:00
|
|
|
size_t orig_loc_num = loc_num;
|
2010-02-23 22:07:08 +08:00
|
|
|
|
|
|
|
FILE *fp = fopen (LOCALE_ALIAS, "rt");
|
|
|
|
if (!fp)
|
|
|
|
return;
|
|
|
|
strcpy (orig_locale, setlocale (LC_CTYPE, NULL));
|
|
|
|
while (fgets (alias_buf, LOCALE_ALIAS_LINE_LEN + 1, fp))
|
|
|
|
{
|
|
|
|
alias_buf[LOCALE_ALIAS_LINE_LEN] = '\0';
|
|
|
|
c = strrchr (alias_buf, '\n');
|
|
|
|
if (c)
|
2011-12-18 07:39:47 +08:00
|
|
|
*c = '\0';
|
2010-02-23 22:07:08 +08:00
|
|
|
c = alias_buf;
|
|
|
|
c += strspn (c, " \t");
|
|
|
|
if (!*c || *c == '#')
|
2011-12-18 07:39:47 +08:00
|
|
|
continue;
|
2010-02-23 22:07:08 +08:00
|
|
|
alias = c;
|
|
|
|
c += strcspn (c, " \t");
|
|
|
|
*c++ = '\0';
|
|
|
|
c += strspn (c, " \t");
|
|
|
|
if (*c == '#')
|
2011-12-18 07:39:47 +08:00
|
|
|
continue;
|
2010-02-23 22:07:08 +08:00
|
|
|
replace = c;
|
|
|
|
c += strcspn (c, " \t");
|
|
|
|
*c++ = '\0';
|
|
|
|
c = strchr (replace, '.');
|
|
|
|
if (c)
|
|
|
|
*c = '\0';
|
2023-02-23 07:22:56 +08:00
|
|
|
/* Ignore "ja_JP" and "ko_KR" locales from here, they are in the Windows
|
|
|
|
DB anyway. */
|
|
|
|
if (!strcmp (alias, "ja_JP") || !strcmp (alias, "ko_KR"))
|
|
|
|
continue;
|
2010-02-23 22:07:08 +08:00
|
|
|
search.name = replace;
|
2010-03-24 05:26:03 +08:00
|
|
|
loc = (loc_t *) bsearch (&search, locale, orig_loc_num, sizeof (loc_t),
|
2010-02-23 22:07:08 +08:00
|
|
|
compare_locales);
|
2023-02-23 07:22:56 +08:00
|
|
|
|
2010-02-23 22:07:08 +08:00
|
|
|
add_locale (alias, loc ? loc->language : L"", loc ? loc->territory : L"",
|
|
|
|
true);
|
|
|
|
}
|
|
|
|
fclose (fp);
|
2010-02-17 23:01:56 +08:00
|
|
|
}
|
|
|
|
|
2023-02-23 07:22:56 +08:00
|
|
|
BOOL
|
|
|
|
print_all_locales_proc (LPWSTR loc_name, DWORD info, LPARAM param)
|
2010-02-17 23:01:56 +08:00
|
|
|
{
|
2023-02-23 07:22:56 +08:00
|
|
|
wchar_t iso639[32] = { 0 };
|
|
|
|
wchar_t iso3166[32] = { 0 };
|
|
|
|
wchar_t iso15924[32] = { 0 };
|
2010-02-17 23:01:56 +08:00
|
|
|
DWORD cp;
|
|
|
|
|
2023-02-23 07:22:56 +08:00
|
|
|
#if 0
|
|
|
|
struct {
|
|
|
|
wchar_t language[256];
|
|
|
|
wchar_t country[256];
|
|
|
|
char loc[32];
|
|
|
|
} loc_list[32];
|
|
|
|
int lcnt = 0;
|
|
|
|
#endif
|
2010-02-17 23:01:56 +08:00
|
|
|
|
2023-02-23 07:22:56 +08:00
|
|
|
if (getlocale (loc_name, iso639, iso3166, iso15924))
|
2010-02-17 23:01:56 +08:00
|
|
|
{
|
2023-02-23 07:22:56 +08:00
|
|
|
char *c, posix_loc[32];
|
|
|
|
wchar_t language[256];
|
|
|
|
wchar_t country[256];
|
|
|
|
wchar_t currency[9];
|
|
|
|
|
|
|
|
c = posix_loc + snprintf (posix_loc, sizeof posix_loc, "%ls_%ls",
|
|
|
|
iso639, iso3166);
|
|
|
|
/* Inuktitut: equivalent @latin due to lack of info on Linux */
|
|
|
|
if (!wcscmp (iso639, L"iu"))
|
2010-02-17 23:01:56 +08:00
|
|
|
{
|
2023-02-23 07:22:56 +08:00
|
|
|
if (wcscmp (iso15924, L"Latn;"))
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
/* Javanese: only use @latin locale. */
|
|
|
|
else if (!wcscmp (iso639, L"jv"))
|
|
|
|
{
|
|
|
|
if (wcscmp (iso15924, L"Latn;"))
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
/* Mongolian: only use @mongolian locale. */
|
|
|
|
else if (!wcscmp (iso639, L"mn"))
|
|
|
|
{
|
|
|
|
if (wcscmp (iso15924, L"Mong;"))
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
/* Serbian: Windows default is Latin, Linux default is Cyrillic.
|
|
|
|
We want the Linux default and attach @latin otherwise */
|
|
|
|
else if (!wcscmp (iso639, L"sr") && !wcscmp (iso15924, L"Latn;"))
|
|
|
|
stpcpy (c, "@latin");
|
|
|
|
/* Tamazight: no modifier, iso639 is "ber" on Linux.
|
|
|
|
"zgh-Tfng-MA" is equivalent to "ber_MA". */
|
|
|
|
else if (!wcscmp (iso639, L"zgh"))
|
|
|
|
snprintf (posix_loc, sizeof posix_loc, "ber_%.27ls", iso3166);
|
|
|
|
/* Tamazight: "tzm-Latn-DZ" is equivalent to "ber_DZ",
|
|
|
|
skip everything else. */
|
|
|
|
else if (!wcscmp (iso639, L"tzm"))
|
|
|
|
{
|
|
|
|
if (!wcscmp (iso3166, L"DZ") && !wcscmp (iso15924, L"Latn;"))
|
|
|
|
snprintf (posix_loc, sizeof posix_loc, "ber_%.27ls", iso3166);
|
|
|
|
else
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
/* In all other cases, we check if the script from the Windows
|
|
|
|
locale is the default locale in that language. If not, we
|
|
|
|
add it as modifier if possible, or skip it */
|
|
|
|
else if (iso15924[0])
|
|
|
|
{
|
|
|
|
wchar_t scriptless_win_locale[32];
|
|
|
|
wchar_t default_iso15924[32];
|
|
|
|
|
2023-02-25 20:20:05 +08:00
|
|
|
wcpcpy (wcpcpy (wcpcpy (scriptless_win_locale, iso639), L"-"),
|
2023-02-23 07:22:56 +08:00
|
|
|
iso3166);
|
|
|
|
if ((GetLocaleInfoEx (scriptless_win_locale, LOCALE_SSCRIPTS,
|
|
|
|
default_iso15924, 32)
|
|
|
|
|| GetLocaleInfoEx (iso639, LOCALE_SSCRIPTS,
|
|
|
|
default_iso15924, 32))
|
|
|
|
&& !wcsstr (default_iso15924, iso15924))
|
2010-02-17 23:01:56 +08:00
|
|
|
{
|
2023-02-23 07:22:56 +08:00
|
|
|
if (!wcscmp (iso15924, L"Latn;"))
|
2010-02-17 23:01:56 +08:00
|
|
|
stpcpy (c, "@latin");
|
2023-02-23 07:22:56 +08:00
|
|
|
else if (!wcscmp (iso15924, L"Cyrl;"))
|
2010-02-17 23:01:56 +08:00
|
|
|
stpcpy (c, "@cyrillic");
|
2023-02-23 07:22:56 +08:00
|
|
|
else if (!wcscmp (iso15924, L"Deva;"))
|
|
|
|
stpcpy (c, "@devanagari");
|
|
|
|
else if (!wcscmp (iso15924, L"Adlm;"))
|
|
|
|
stpcpy (c, "@adlam");
|
2010-02-17 23:01:56 +08:00
|
|
|
else
|
2023-02-23 07:22:56 +08:00
|
|
|
return TRUE;
|
2010-02-17 23:01:56 +08:00
|
|
|
}
|
|
|
|
}
|
2023-02-23 07:22:56 +08:00
|
|
|
|
|
|
|
/* Print */
|
|
|
|
GetLocaleInfoEx (loc_name, LOCALE_SENGLISHLANGUAGENAME, language, 256);
|
|
|
|
GetLocaleInfoEx (loc_name, LOCALE_SENGLISHCOUNTRYNAME, country, 256);
|
|
|
|
add_locale (posix_loc, language, country);
|
|
|
|
/* Check for locales sporting an additional modifier for
|
|
|
|
changing the codeset and other stuff. */
|
|
|
|
if (!wcscmp (iso639, L"be") && !wcscmp (iso3166, L"BY"))
|
|
|
|
stpcpy (c, "@latin");
|
|
|
|
if (!wcscmp (iso639, L"tt") && !wcscmp (iso3166, L"RU"))
|
|
|
|
stpcpy (c, "@iqtelif");
|
|
|
|
else if (GetLocaleInfoEx (loc_name,
|
|
|
|
LOCALE_IDEFAULTANSICODEPAGE
|
|
|
|
| LOCALE_RETURN_NUMBER,
|
|
|
|
(PWCHAR) &cp, sizeof cp)
|
|
|
|
&& cp == 1252 /* Latin1*/
|
|
|
|
&& GetLocaleInfoEx (loc_name, LOCALE_SINTLSYMBOL, currency, 9)
|
|
|
|
&& !wcsncmp (currency, L"EUR", 3))
|
|
|
|
stpcpy (c, "@euro");
|
|
|
|
else if (!wcscmp (iso639, L"ja")
|
|
|
|
|| !wcscmp (iso639, L"ko")
|
|
|
|
|| !wcscmp (iso639, L"zh"))
|
|
|
|
stpcpy (c, "@cjknarrow");
|
|
|
|
else
|
|
|
|
return TRUE;
|
|
|
|
add_locale (posix_loc, language, country);
|
2010-02-17 23:01:56 +08:00
|
|
|
}
|
2023-02-23 07:22:56 +08:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
print_all_locales (int verbose)
|
|
|
|
{
|
|
|
|
add_locale ("C", L"C", L"POSIX");
|
|
|
|
add_locale ("POSIX", L"C", L"POSIX", true);
|
|
|
|
EnumSystemLocalesEx (print_all_locales_proc,
|
|
|
|
LOCALE_WINDOWS | LOCALE_SUPPLEMENTAL,
|
|
|
|
0, NULL);
|
2010-02-23 22:07:08 +08:00
|
|
|
/* First sort allows add_locale_alias_locales to bsearch in locales. */
|
|
|
|
qsort (locale, loc_num, sizeof (loc_t), compare_locales);
|
|
|
|
add_locale_alias_locales ();
|
|
|
|
qsort (locale, loc_num, sizeof (loc_t), compare_locales);
|
|
|
|
for (size_t i = 0; i < loc_num; ++i)
|
|
|
|
print_locale (verbose, &locale[i]);
|
2010-02-17 23:01:56 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
print_charmaps ()
|
|
|
|
{
|
|
|
|
/* FIXME: We need a method to fetch the available charsets from Cygwin, */
|
|
|
|
const char *charmaps[] =
|
|
|
|
{
|
|
|
|
"ASCII",
|
|
|
|
"BIG5",
|
|
|
|
"CP1125",
|
|
|
|
"CP1250",
|
|
|
|
"CP1251",
|
|
|
|
"CP1252",
|
|
|
|
"CP1253",
|
|
|
|
"CP1254",
|
|
|
|
"CP1255",
|
|
|
|
"CP1256",
|
|
|
|
"CP1257",
|
|
|
|
"CP1258",
|
|
|
|
"CP437",
|
|
|
|
"CP720",
|
|
|
|
"CP737",
|
|
|
|
"CP775",
|
|
|
|
"CP850",
|
|
|
|
"CP852",
|
|
|
|
"CP855",
|
|
|
|
"CP857",
|
|
|
|
"CP858",
|
|
|
|
"CP862",
|
|
|
|
"CP866",
|
|
|
|
"CP874",
|
|
|
|
"CP932",
|
2010-03-28 05:08:02 +08:00
|
|
|
"EUC-CN",
|
2010-02-17 23:01:56 +08:00
|
|
|
"EUC-JP",
|
|
|
|
"EUC-KR",
|
2010-03-28 05:08:02 +08:00
|
|
|
"GB2312",
|
2010-02-17 23:01:56 +08:00
|
|
|
"GBK",
|
|
|
|
"GEORGIAN-PS",
|
|
|
|
"ISO-8859-1",
|
|
|
|
"ISO-8859-10",
|
|
|
|
"ISO-8859-11",
|
|
|
|
"ISO-8859-13",
|
|
|
|
"ISO-8859-14",
|
|
|
|
"ISO-8859-15",
|
|
|
|
"ISO-8859-16",
|
|
|
|
"ISO-8859-2",
|
|
|
|
"ISO-8859-3",
|
|
|
|
"ISO-8859-4",
|
|
|
|
"ISO-8859-5",
|
|
|
|
"ISO-8859-6",
|
|
|
|
"ISO-8859-7",
|
|
|
|
"ISO-8859-8",
|
|
|
|
"ISO-8859-9",
|
|
|
|
"KOI8-R",
|
2023-02-24 23:07:26 +08:00
|
|
|
"KOI8-T",
|
2010-02-17 23:01:56 +08:00
|
|
|
"KOI8-U",
|
|
|
|
"PT154",
|
|
|
|
"SJIS",
|
|
|
|
"TIS-620",
|
|
|
|
"UTF-8",
|
|
|
|
NULL
|
|
|
|
};
|
|
|
|
const char **charmap = charmaps;
|
|
|
|
while (*charmap)
|
|
|
|
printf ("%s\n", *charmap++);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
print_lc_ivalue (int key, const char *name, int value)
|
|
|
|
{
|
|
|
|
if (key)
|
|
|
|
printf ("%s=", name);
|
|
|
|
printf ("%d", value == CHAR_MAX ? -1 : value);
|
|
|
|
fputc ('\n', stdout);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
print_lc_svalue (int key, const char *name, const char *value)
|
|
|
|
{
|
|
|
|
if (key)
|
|
|
|
printf ("%s=\"", name);
|
|
|
|
fputs (value, stdout);
|
|
|
|
if (key)
|
|
|
|
fputc ('"', stdout);
|
|
|
|
fputc ('\n', stdout);
|
|
|
|
}
|
|
|
|
|
2010-02-20 01:27:05 +08:00
|
|
|
void
|
|
|
|
print_lc_sepstrings (int key, const char *name, const char *value)
|
|
|
|
{
|
|
|
|
char *c;
|
|
|
|
|
|
|
|
if (key)
|
|
|
|
printf ("%s=", name);
|
|
|
|
while (value && *value)
|
|
|
|
{
|
|
|
|
if (key)
|
|
|
|
fputc ('"', stdout);
|
|
|
|
c = strchr (value, ';');
|
|
|
|
if (!c)
|
|
|
|
{
|
|
|
|
fputs (value, stdout);
|
|
|
|
value = NULL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-04-23 17:44:36 +08:00
|
|
|
printf ("%.*s", (int) (c - value), value);
|
2010-02-20 01:27:05 +08:00
|
|
|
value = c + 1;
|
|
|
|
}
|
|
|
|
if (key)
|
|
|
|
fputc ('"', stdout);
|
|
|
|
if (value && *value)
|
2011-12-18 07:39:47 +08:00
|
|
|
fputc (';', stdout);
|
2010-02-20 01:27:05 +08:00
|
|
|
}
|
|
|
|
fputc ('\n', stdout);
|
|
|
|
}
|
|
|
|
|
2010-02-17 23:01:56 +08:00
|
|
|
void
|
|
|
|
print_lc_strings (int key, const char *name, int from, int to)
|
|
|
|
{
|
|
|
|
if (key)
|
|
|
|
printf ("%s=\"", name);
|
|
|
|
for (int i = from; i <= to; ++i)
|
|
|
|
printf ("%s%s", i > from ? ";" : "", nl_langinfo (i));
|
|
|
|
if (key)
|
|
|
|
fputc ('"', stdout);
|
|
|
|
fputc ('\n', stdout);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
print_lc_grouping (int key, const char *name, const char *grouping)
|
|
|
|
{
|
|
|
|
if (key)
|
|
|
|
printf ("%s=", name);
|
|
|
|
for (const char *g = grouping; *g; ++g)
|
|
|
|
printf ("%s%d", g > grouping ? ";" : "", *g == CHAR_MAX ? -1 : *g);
|
|
|
|
fputc ('\n', stdout);
|
|
|
|
}
|
|
|
|
|
|
|
|
enum type_t
|
|
|
|
{
|
|
|
|
is_string_fake,
|
2010-04-28 18:00:40 +08:00
|
|
|
is_grouping,
|
|
|
|
is_string,
|
|
|
|
is_mstrings,
|
|
|
|
is_sepstrings,
|
|
|
|
is_int,
|
|
|
|
is_wchar,
|
2010-02-17 23:01:56 +08:00
|
|
|
is_end
|
|
|
|
};
|
|
|
|
|
|
|
|
struct lc_names_t
|
|
|
|
{
|
|
|
|
const char *name;
|
|
|
|
type_t type;
|
|
|
|
size_t fromval;
|
|
|
|
size_t toval;
|
|
|
|
};
|
|
|
|
|
|
|
|
const char *fake_string[] = {
|
|
|
|
"upper;lower;alpha;digit;xdigit;space;print;graph;blank;cntrl;punct;alnum",
|
|
|
|
"upper\";\"lower\";\"alpha\";\"digit\";\"xdigit\";\"space\";\"print\";\"graph\";\"blank\";\"cntrl\";\"punct\";\"alnum",
|
|
|
|
"toupper;tolower",
|
|
|
|
"toupper\";\"tolower"
|
|
|
|
};
|
|
|
|
|
|
|
|
lc_names_t lc_ctype_names[] =
|
|
|
|
{
|
2023-02-23 07:22:56 +08:00
|
|
|
{ "ctype-class-names", is_string_fake, 0, 0 },
|
|
|
|
{ "ctype-map-names", is_string_fake, 2, 0 },
|
2010-04-28 18:00:40 +08:00
|
|
|
{ "ctype-outdigit0_mb", is_string, _NL_CTYPE_OUTDIGITS0_MB, 0 },
|
|
|
|
{ "ctype-outdigit1_mb", is_string, _NL_CTYPE_OUTDIGITS1_MB, 0 },
|
|
|
|
{ "ctype-outdigit2_mb", is_string, _NL_CTYPE_OUTDIGITS2_MB, 0 },
|
|
|
|
{ "ctype-outdigit3_mb", is_string, _NL_CTYPE_OUTDIGITS3_MB, 0 },
|
|
|
|
{ "ctype-outdigit4_mb", is_string, _NL_CTYPE_OUTDIGITS4_MB, 0 },
|
|
|
|
{ "ctype-outdigit5_mb", is_string, _NL_CTYPE_OUTDIGITS5_MB, 0 },
|
|
|
|
{ "ctype-outdigit6_mb", is_string, _NL_CTYPE_OUTDIGITS6_MB, 0 },
|
|
|
|
{ "ctype-outdigit7_mb", is_string, _NL_CTYPE_OUTDIGITS7_MB, 0 },
|
|
|
|
{ "ctype-outdigit8_mb", is_string, _NL_CTYPE_OUTDIGITS8_MB, 0 },
|
|
|
|
{ "ctype-outdigit9_mb", is_string, _NL_CTYPE_OUTDIGITS9_MB, 0 },
|
2023-02-23 07:22:56 +08:00
|
|
|
{ "ctype-outdigit0_wc", is_wchar, _NL_CTYPE_OUTDIGITS0_WC, 0 },
|
|
|
|
{ "ctype-outdigit1_wc", is_wchar, _NL_CTYPE_OUTDIGITS1_WC, 0 },
|
|
|
|
{ "ctype-outdigit2_wc", is_wchar, _NL_CTYPE_OUTDIGITS2_WC, 0 },
|
|
|
|
{ "ctype-outdigit3_wc", is_wchar, _NL_CTYPE_OUTDIGITS3_WC, 0 },
|
|
|
|
{ "ctype-outdigit4_wc", is_wchar, _NL_CTYPE_OUTDIGITS4_WC, 0 },
|
|
|
|
{ "ctype-outdigit5_wc", is_wchar, _NL_CTYPE_OUTDIGITS5_WC, 0 },
|
|
|
|
{ "ctype-outdigit6_wc", is_wchar, _NL_CTYPE_OUTDIGITS6_WC, 0 },
|
|
|
|
{ "ctype-outdigit7_wc", is_wchar, _NL_CTYPE_OUTDIGITS7_WC, 0 },
|
|
|
|
{ "ctype-outdigit8_wc", is_wchar, _NL_CTYPE_OUTDIGITS8_WC, 0 },
|
|
|
|
{ "ctype-outdigit9_wc", is_wchar, _NL_CTYPE_OUTDIGITS9_WC, 0 },
|
2010-04-28 18:00:40 +08:00
|
|
|
{ "charmap", is_string, CODESET, 0 },
|
|
|
|
{ "ctype-mb-cur-max", is_int, _NL_CTYPE_MB_CUR_MAX, 0 },
|
2023-02-23 07:22:56 +08:00
|
|
|
{ NULL, is_end, 0, 0 }
|
2010-02-17 23:01:56 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
lc_names_t lc_numeric_names[] =
|
|
|
|
{
|
2010-04-28 18:00:40 +08:00
|
|
|
{ "decimal_point", is_string, RADIXCHAR, 0 },
|
2023-02-23 07:22:56 +08:00
|
|
|
{ "thousands_sep", is_string, THOUSEP, 0 },
|
2010-04-28 18:00:40 +08:00
|
|
|
{ "grouping", is_grouping, _NL_NUMERIC_GROUPING, 0 },
|
|
|
|
{ "numeric-decimal-point-wc", is_wchar, _NL_NUMERIC_DECIMAL_POINT_WC, 0 },
|
|
|
|
{ "numeric-thousands-sep-wc", is_wchar, _NL_NUMERIC_THOUSANDS_SEP_WC, 0 },
|
|
|
|
{ "numeric-codeset", is_string, _NL_NUMERIC_CODESET, 0 },
|
2023-02-23 07:22:56 +08:00
|
|
|
{ NULL, is_end, 0, 0 }
|
2010-02-17 23:01:56 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
lc_names_t lc_time_names[] =
|
|
|
|
{
|
2010-04-28 18:00:40 +08:00
|
|
|
{ "abday", is_mstrings, ABDAY_1, ABDAY_7 },
|
|
|
|
{ "day", is_mstrings, DAY_1, DAY_7 },
|
|
|
|
{ "abmon", is_mstrings, ABMON_1, ABMON_12 },
|
|
|
|
{ "mon", is_mstrings, MON_1, MON_12 },
|
|
|
|
{ "am_pm", is_mstrings, AM_STR, PM_STR },
|
|
|
|
{ "d_t_fmt", is_string, D_T_FMT, 0 },
|
|
|
|
{ "d_fmt", is_string, D_FMT, 0 },
|
|
|
|
{ "t_fmt", is_string, T_FMT, 0 },
|
|
|
|
{ "t_fmt_ampm", is_string, T_FMT_AMPM, 0 },
|
|
|
|
{ "era", is_sepstrings, ERA, 0 },
|
|
|
|
{ "era_d_fmt", is_string, ERA_D_FMT, 0 },
|
|
|
|
{ "alt_digits", is_sepstrings,ALT_DIGITS, 0 },
|
|
|
|
{ "era_d_t_fmt", is_string, ERA_D_T_FMT, 0 },
|
|
|
|
{ "era_t_fmt", is_string, ERA_T_FMT, 0 },
|
|
|
|
{ "date_fmt", is_string, _DATE_FMT, 0 },
|
|
|
|
{ "time-codeset", is_string, _NL_TIME_CODESET, 0 },
|
2023-02-23 07:22:56 +08:00
|
|
|
{ NULL, is_end, 0, 0 }
|
2010-02-17 23:01:56 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
lc_names_t lc_collate_names[] =
|
|
|
|
{
|
2010-04-28 18:00:40 +08:00
|
|
|
{ "collate-codeset", is_string, _NL_COLLATE_CODESET, 0 },
|
2023-02-23 07:22:56 +08:00
|
|
|
{ NULL, is_end, 0, 0 }
|
2010-02-17 23:01:56 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
lc_names_t lc_monetary_names[] =
|
|
|
|
{
|
2010-04-28 18:00:40 +08:00
|
|
|
{ "int_curr_symbol", is_string, _NL_MONETARY_INT_CURR_SYMBOL, 0 },
|
|
|
|
{ "currency_symbol", is_string, _NL_MONETARY_CURRENCY_SYMBOL, 0 },
|
|
|
|
{ "mon_decimal_point", is_string, _NL_MONETARY_MON_DECIMAL_POINT, 0 },
|
|
|
|
{ "mon_thousands_sep", is_string, _NL_MONETARY_MON_THOUSANDS_SEP, 0 },
|
|
|
|
{ "mon_grouping", is_grouping, _NL_MONETARY_MON_GROUPING, 0 },
|
|
|
|
{ "positive_sign", is_string, _NL_MONETARY_POSITIVE_SIGN, 0 },
|
|
|
|
{ "negative_sign", is_string, _NL_MONETARY_NEGATIVE_SIGN, 0 },
|
|
|
|
{ "int_frac_digits", is_int, _NL_MONETARY_INT_FRAC_DIGITS, 0 },
|
|
|
|
{ "frac_digits", is_int, _NL_MONETARY_FRAC_DIGITS, 0 },
|
|
|
|
{ "p_cs_precedes", is_int, _NL_MONETARY_P_CS_PRECEDES, 0 },
|
|
|
|
{ "p_sep_by_space", is_int, _NL_MONETARY_P_SEP_BY_SPACE, 0 },
|
|
|
|
{ "n_cs_precedes", is_int, _NL_MONETARY_N_CS_PRECEDES, 0 },
|
|
|
|
{ "n_sep_by_space", is_int, _NL_MONETARY_N_SEP_BY_SPACE, 0 },
|
|
|
|
{ "p_sign_posn", is_int, _NL_MONETARY_P_SIGN_POSN, 0 },
|
|
|
|
{ "n_sign_posn", is_int, _NL_MONETARY_N_SIGN_POSN, 0 },
|
|
|
|
{ "int_p_cs_precedes", is_int, _NL_MONETARY_INT_P_CS_PRECEDES, 0 },
|
|
|
|
{ "int_p_sep_by_space", is_int, _NL_MONETARY_INT_P_SEP_BY_SPACE,0 },
|
|
|
|
{ "int_n_cs_precedes", is_int, _NL_MONETARY_INT_N_CS_PRECEDES, 0 },
|
|
|
|
{ "int_n_sep_by_space", is_int, _NL_MONETARY_INT_N_SEP_BY_SPACE,0 },
|
|
|
|
{ "int_p_sign_posn", is_int, _NL_MONETARY_INT_P_SIGN_POSN, 0 },
|
|
|
|
{ "int_n_sign_posn", is_int, _NL_MONETARY_INT_N_SIGN_POSN, 0 },
|
|
|
|
{ "monetary-decimal-point-wc", is_wchar, _NL_MONETARY_WMON_DECIMAL_POINT, 0 },
|
|
|
|
{ "monetary-thousands-sep-wc", is_wchar, _NL_MONETARY_WMON_THOUSANDS_SEP, 0 },
|
|
|
|
{ "monetary-codeset", is_string, _NL_MONETARY_CODESET, 0 },
|
2023-02-23 07:22:56 +08:00
|
|
|
{ NULL, is_end, 0, 0 }
|
2010-02-17 23:01:56 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
lc_names_t lc_messages_names[] =
|
|
|
|
{
|
2010-04-28 18:00:40 +08:00
|
|
|
{ "yesexpr", is_string, YESEXPR, 0 },
|
|
|
|
{ "noexpr", is_string, NOEXPR, 0 },
|
|
|
|
{ "yesstr", is_string, YESSTR, 0 },
|
|
|
|
{ "nostr", is_string, NOSTR, 0 },
|
|
|
|
{ "messages-codeset", is_string, _NL_MESSAGES_CODESET, 0 },
|
2023-02-23 07:22:56 +08:00
|
|
|
{ NULL, is_end, 0, 0 }
|
2010-02-17 23:01:56 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
void
|
|
|
|
print_lc (int cat, int key, const char *category, const char *name,
|
|
|
|
lc_names_t *lc_name)
|
|
|
|
{
|
|
|
|
if (cat)
|
|
|
|
printf ("%s\n", category);
|
|
|
|
for (lc_names_t *lc = lc_name; lc->type != is_end; ++lc)
|
|
|
|
if (!name || !strcmp (name, lc->name))
|
|
|
|
switch (lc->type)
|
2011-12-18 07:39:47 +08:00
|
|
|
{
|
2010-02-17 23:01:56 +08:00
|
|
|
case is_string_fake:
|
|
|
|
print_lc_svalue (key, lc->name, fake_string[lc->fromval + key]);
|
|
|
|
break;
|
2010-04-28 18:00:40 +08:00
|
|
|
case is_grouping:
|
|
|
|
print_lc_grouping (key, lc->name, nl_langinfo (lc->fromval));
|
2010-02-17 23:01:56 +08:00
|
|
|
break;
|
2010-04-28 18:00:40 +08:00
|
|
|
case is_string:
|
2010-02-17 23:01:56 +08:00
|
|
|
print_lc_svalue (key, lc->name, nl_langinfo (lc->fromval));
|
|
|
|
break;
|
2010-04-28 18:00:40 +08:00
|
|
|
case is_sepstrings:
|
2010-02-20 01:27:05 +08:00
|
|
|
print_lc_sepstrings (key, lc->name, nl_langinfo (lc->fromval));
|
|
|
|
break;
|
2010-04-28 18:00:40 +08:00
|
|
|
case is_mstrings:
|
2010-02-17 23:01:56 +08:00
|
|
|
print_lc_strings (key, lc->name, lc->fromval, lc->toval);
|
|
|
|
break;
|
2010-04-28 18:00:40 +08:00
|
|
|
case is_int:
|
|
|
|
print_lc_ivalue (key, lc->name, (int) *nl_langinfo (lc->fromval));
|
2010-02-17 23:01:56 +08:00
|
|
|
break;
|
2010-04-28 18:00:40 +08:00
|
|
|
case is_wchar:
|
|
|
|
print_lc_ivalue (key, lc->name,
|
|
|
|
*(wchar_t *) nl_langinfo (lc->fromval));
|
2010-02-17 23:01:56 +08:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
struct cat_t
|
|
|
|
{
|
|
|
|
const char *category;
|
|
|
|
int lc_cat;
|
|
|
|
lc_names_t *lc_names;
|
|
|
|
} categories[] =
|
|
|
|
{
|
|
|
|
{ "LC_CTYPE", LC_CTYPE, lc_ctype_names },
|
|
|
|
{ "LC_NUMERIC", LC_NUMERIC, lc_numeric_names },
|
|
|
|
{ "LC_TIME", LC_TIME, lc_time_names },
|
|
|
|
{ "LC_COLLATE", LC_COLLATE, lc_collate_names },
|
|
|
|
{ "LC_MONETARY", LC_MONETARY, lc_monetary_names },
|
|
|
|
{ "LC_MESSAGES", LC_MESSAGES, lc_messages_names },
|
|
|
|
{ NULL, 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
void
|
|
|
|
print_names (int cat, int key, const char *name)
|
|
|
|
{
|
|
|
|
struct cat_t *c;
|
|
|
|
lc_names_t *lc;
|
|
|
|
|
|
|
|
for (c = categories; c->category; ++c)
|
|
|
|
if (!strcmp (name, c->category))
|
|
|
|
{
|
2011-12-18 07:39:47 +08:00
|
|
|
print_lc (cat, key, c->category, NULL, c->lc_names);
|
2010-02-17 23:01:56 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
for (c = categories; c->category; ++c)
|
|
|
|
for (lc = c->lc_names; lc->type != is_end; ++lc)
|
|
|
|
if (!strcmp (name, lc->name))
|
|
|
|
{
|
2011-12-18 07:39:47 +08:00
|
|
|
print_lc (cat, key, c->category, lc->name, lc);
|
2010-02-17 23:01:56 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
print_lc ()
|
|
|
|
{
|
|
|
|
printf ("LANG=%s\n", getenv ("LANG") ?: "");
|
|
|
|
printf ("LC_CTYPE=\"%s\"\n", setlocale (LC_CTYPE, NULL));
|
|
|
|
printf ("LC_NUMERIC=\"%s\"\n", setlocale (LC_NUMERIC, NULL));
|
|
|
|
printf ("LC_TIME=\"%s\"\n", setlocale (LC_TIME, NULL));
|
|
|
|
printf ("LC_COLLATE=\"%s\"\n", setlocale (LC_COLLATE, NULL));
|
|
|
|
printf ("LC_MONETARY=\"%s\"\n", setlocale (LC_MONETARY, NULL));
|
|
|
|
printf ("LC_MESSAGES=\"%s\"\n", setlocale (LC_MESSAGES, NULL));
|
|
|
|
printf ("LC_ALL=%s\n", getenv ("LC_ALL") ?: "");
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
main (int argc, char **argv)
|
|
|
|
{
|
|
|
|
int opt;
|
2023-02-23 07:22:56 +08:00
|
|
|
wchar_t loc_name[256] = { 0 };
|
2010-02-17 23:01:56 +08:00
|
|
|
int all = 0;
|
|
|
|
int cat = 0;
|
|
|
|
int key = 0;
|
|
|
|
int maps = 0;
|
|
|
|
int verbose = 0;
|
|
|
|
const char *utf = "";
|
|
|
|
|
|
|
|
setlocale (LC_ALL, "");
|
2011-10-10 22:57:48 +08:00
|
|
|
while ((opt = getopt_long (argc, argv, opts, longopts, NULL)) != -1)
|
2010-02-17 23:01:56 +08:00
|
|
|
switch (opt)
|
|
|
|
{
|
|
|
|
case 'a':
|
2011-12-18 07:39:47 +08:00
|
|
|
all = 1;
|
2010-02-17 23:01:56 +08:00
|
|
|
break;
|
|
|
|
case 'c':
|
2011-12-18 07:39:47 +08:00
|
|
|
cat = 1;
|
2010-02-17 23:01:56 +08:00
|
|
|
break;
|
|
|
|
case 'k':
|
2011-12-18 07:39:47 +08:00
|
|
|
key = 1;
|
2010-02-17 23:01:56 +08:00
|
|
|
break;
|
|
|
|
case 'm':
|
|
|
|
maps = 1;
|
|
|
|
break;
|
2016-08-17 16:58:04 +08:00
|
|
|
case 'i':
|
2023-02-23 07:22:56 +08:00
|
|
|
GetLocaleInfoW ((UINT_PTR) GetKeyboardLayout (0) & 0xffff, LOCALE_SNAME,
|
|
|
|
loc_name, 256);
|
2016-08-17 16:58:04 +08:00
|
|
|
break;
|
2010-02-17 23:01:56 +08:00
|
|
|
case 's':
|
2023-02-23 07:22:56 +08:00
|
|
|
GetLocaleInfoW (GetSystemDefaultUILanguage (), LOCALE_SNAME,
|
|
|
|
loc_name, 256);
|
2010-02-17 23:01:56 +08:00
|
|
|
break;
|
|
|
|
case 'u':
|
2023-02-23 07:22:56 +08:00
|
|
|
GetLocaleInfoW (GetUserDefaultUILanguage (), LOCALE_SNAME,
|
|
|
|
loc_name, 256);
|
2011-10-10 17:50:43 +08:00
|
|
|
break;
|
|
|
|
case 'f':
|
2023-02-23 07:22:56 +08:00
|
|
|
GetUserDefaultLocaleName (loc_name, 256);
|
2011-10-10 17:50:43 +08:00
|
|
|
break;
|
|
|
|
case 'n':
|
2023-02-23 07:22:56 +08:00
|
|
|
GetSystemDefaultLocaleName (loc_name, 256);
|
2010-02-17 23:01:56 +08:00
|
|
|
break;
|
|
|
|
case 'U':
|
2011-12-18 07:39:47 +08:00
|
|
|
utf = ".UTF-8";
|
2010-02-17 23:01:56 +08:00
|
|
|
break;
|
|
|
|
case 'v':
|
|
|
|
verbose = 1;
|
|
|
|
break;
|
|
|
|
case 'h':
|
2011-10-10 17:50:43 +08:00
|
|
|
usage ();
|
|
|
|
case 'V':
|
|
|
|
print_version ();
|
|
|
|
return 0;
|
2010-02-17 23:01:56 +08:00
|
|
|
default:
|
2011-10-10 22:57:48 +08:00
|
|
|
fprintf (stderr, "Try `%s --help' for more information.\n",
|
|
|
|
program_invocation_short_name);
|
2011-10-10 17:50:43 +08:00
|
|
|
return 1;
|
2010-02-17 23:01:56 +08:00
|
|
|
}
|
|
|
|
if (all)
|
|
|
|
print_all_locales (verbose);
|
|
|
|
else if (maps)
|
|
|
|
print_charmaps ();
|
2023-02-23 07:22:56 +08:00
|
|
|
else if (loc_name[0])
|
2010-02-17 23:01:56 +08:00
|
|
|
{
|
2023-02-23 07:22:56 +08:00
|
|
|
wchar_t iso639[10];
|
|
|
|
wchar_t iso3166[10];
|
|
|
|
|
|
|
|
if (getlocale (loc_name, iso639, iso3166, NULL))
|
|
|
|
printf ("%ls_%ls%s", iso639, iso3166, utf);
|
2010-02-17 23:01:56 +08:00
|
|
|
}
|
|
|
|
else if (optind < argc)
|
|
|
|
while (optind < argc)
|
|
|
|
print_names (cat, key, argv[optind++]);
|
|
|
|
else
|
|
|
|
print_lc ();
|
|
|
|
return 0;
|
|
|
|
}
|