* locale.cc (printlocale): Remove.
(loc_t): New type to keep locale information for printing. (print_codeset): New function to print codeset as on Linux. (print_locale_with_codeset): New function to print single locale. Print verbose style as the Linux locale(1) tool. (print_locale): New function to print single locale plus its UTF-8 variation, if available. (compare_locales): New helper function for bsearch and qsort on loc_t. (add_locale): New function to store locale in loc_t array. (add_locale_alias_locales): New function to store locales from locale.alias file in loc_t. (print_all_locales): Call add_locale instead of printlocale. Call add_locale_alias_locales, sort locales alphabetically and print them.
This commit is contained in:
parent
ed64b7583c
commit
a2036998b1
|
@ -1,3 +1,20 @@
|
||||||
|
2010-02-23 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* locale.cc (printlocale): Remove.
|
||||||
|
(loc_t): New type to keep locale information for printing.
|
||||||
|
(print_codeset): New function to print codeset as on Linux.
|
||||||
|
(print_locale_with_codeset): New function to print single locale.
|
||||||
|
Print verbose style as the Linux locale(1) tool.
|
||||||
|
(print_locale): New function to print single locale plus its UTF-8
|
||||||
|
variation, if available.
|
||||||
|
(compare_locales): New helper function for bsearch and qsort on loc_t.
|
||||||
|
(add_locale): New function to store locale in loc_t array.
|
||||||
|
(add_locale_alias_locales): New function to store locales from
|
||||||
|
locale.alias file in loc_t.
|
||||||
|
(print_all_locales): Call add_locale instead of printlocale.
|
||||||
|
Call add_locale_alias_locales, sort locales alphabetically and print
|
||||||
|
them.
|
||||||
|
|
||||||
2010-02-22 Christopher Faylor <me+cygwin@cgf.cx>
|
2010-02-22 Christopher Faylor <me+cygwin@cgf.cx>
|
||||||
|
|
||||||
* strace.cc (mnemonic_table): Add "special" mask option.
|
* strace.cc (mnemonic_table): Add "special" mask option.
|
||||||
|
|
|
@ -24,15 +24,20 @@
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <ctype.h>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
#include <langinfo.h>
|
#include <langinfo.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <sys/cygwin.h>
|
||||||
#define WINVER 0x0601
|
#define WINVER 0x0601
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
|
#define LOCALE_ALIAS "/usr/share/locale/locale.alias"
|
||||||
|
#define LOCALE_ALIAS_LINE_LEN 255
|
||||||
|
|
||||||
extern char *__progname;
|
extern char *__progname;
|
||||||
|
|
||||||
void usage (FILE *, int) __attribute__ ((noreturn));
|
void usage (FILE *, int) __attribute__ ((noreturn));
|
||||||
|
@ -89,14 +94,155 @@ getlocale (LCID lcid, char *name)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
void
|
void
|
||||||
printlocale (int verbose, const char *loc,
|
print_codeset (const char *codeset)
|
||||||
const wchar_t *lang, const wchar_t *ctry)
|
|
||||||
{
|
{
|
||||||
printf ("%-16s", loc);
|
for (; *codeset; ++codeset)
|
||||||
|
if (*codeset != '-')
|
||||||
|
putc (tolower ((int)(unsigned char) *codeset), stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
print_locale_with_codeset (int verbose, loc_t *locale, const char *name,
|
||||||
|
bool utf8, const char *modifier)
|
||||||
|
{
|
||||||
|
static const char *sysroot;
|
||||||
|
char locname[32];
|
||||||
|
|
||||||
|
if (verbose
|
||||||
|
&& (!strcmp (locale->name, "C") || !strcmp (locale->name, "POSIX")))
|
||||||
|
return;
|
||||||
|
if (!sysroot)
|
||||||
|
{
|
||||||
|
char sysbuf[PATH_MAX];
|
||||||
|
stpcpy (stpcpy (sysbuf, getenv ("SYSTEMROOT")),
|
||||||
|
"\\system32\\kernel32.dll");
|
||||||
|
sysroot = (const char *) cygwin_create_path (CCP_WIN_A_TO_POSIX, sysbuf);
|
||||||
|
if (!sysroot)
|
||||||
|
sysroot = "kernel32.dll";
|
||||||
|
}
|
||||||
|
stpcpy (stpcpy (stpcpy (locname, name), utf8 ? ".utf8" : ""), modifier ?: "");
|
||||||
if (verbose)
|
if (verbose)
|
||||||
printf ("%ls (%ls)", lang, ctry);
|
fputs ("locale: ", stdout);
|
||||||
fputc ('\n', stdout);
|
printf ("%-15s ", locname);
|
||||||
|
if (verbose)
|
||||||
|
{
|
||||||
|
printf ("archive: %s\n",
|
||||||
|
locale->alias ? LOCALE_ALIAS : sysroot);
|
||||||
|
puts ("-------------------------------------------------------------------------------");
|
||||||
|
printf (" language | %ls\n", locale->language);
|
||||||
|
printf ("territory | %ls\n", locale->territory);
|
||||||
|
printf (" codeset | %s\n", utf8 ? "UTF-8" : locale->codeset);
|
||||||
|
}
|
||||||
|
putc ('\n', stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
print_locale (int verbose, loc_t *locale)
|
||||||
|
{
|
||||||
|
print_locale_with_codeset (verbose, locale, locale->name, false, NULL);
|
||||||
|
char *modifier = strchr (locale->name, '@');
|
||||||
|
if (!locale->alias)
|
||||||
|
{
|
||||||
|
if (!modifier)
|
||||||
|
print_locale_with_codeset (verbose, locale, locale->name, true, NULL);
|
||||||
|
else if (!strcmp (modifier, "@cjknarrow"))
|
||||||
|
{
|
||||||
|
*modifier++ = '\0';
|
||||||
|
print_locale_with_codeset (verbose, locale, locale->name, true,
|
||||||
|
modifier);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
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)
|
||||||
|
*c = '\0';
|
||||||
|
c = alias_buf;
|
||||||
|
c += strspn (c, " \t");
|
||||||
|
if (!*c || *c == '#')
|
||||||
|
continue;
|
||||||
|
alias = c;
|
||||||
|
c += strcspn (c, " \t");
|
||||||
|
*c++ = '\0';
|
||||||
|
c += strspn (c, " \t");
|
||||||
|
if (*c == '#')
|
||||||
|
continue;
|
||||||
|
replace = c;
|
||||||
|
c += strcspn (c, " \t");
|
||||||
|
*c++ = '\0';
|
||||||
|
c = strchr (replace, '.');
|
||||||
|
if (c)
|
||||||
|
*c = '\0';
|
||||||
|
search.name = replace;
|
||||||
|
loc = (loc_t *) bsearch (&search, locale, loc_num, sizeof (loc_t),
|
||||||
|
compare_locales);
|
||||||
|
add_locale (alias, loc ? loc->language : L"", loc ? loc->territory : L"",
|
||||||
|
true);
|
||||||
|
}
|
||||||
|
fclose (fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -108,8 +254,8 @@ print_all_locales (int verbose)
|
||||||
|
|
||||||
unsigned lang, sublang;
|
unsigned lang, sublang;
|
||||||
|
|
||||||
printlocale (verbose, "C", L"C", L"POSIX");
|
add_locale ("C", L"C", L"POSIX");
|
||||||
printlocale (verbose, "POSIX", L"C", L"POSIX");
|
add_locale ("POSIX", L"C", L"POSIX", true);
|
||||||
for (lang = 1; lang <= 0xff; ++lang)
|
for (lang = 1; lang <= 0xff; ++lang)
|
||||||
{
|
{
|
||||||
struct {
|
struct {
|
||||||
|
@ -176,7 +322,7 @@ print_all_locales (int verbose)
|
||||||
if (lcnt < 32)
|
if (lcnt < 32)
|
||||||
strcpy (loc_list[lcnt++].loc, loc);
|
strcpy (loc_list[lcnt++].loc, loc);
|
||||||
/* Print */
|
/* Print */
|
||||||
printlocale (verbose, loc, language, country);
|
add_locale (loc, language, country);
|
||||||
/* Check for locales which sport a modifier for
|
/* Check for locales which sport a modifier for
|
||||||
changing the codeset and other stuff. */
|
changing the codeset and other stuff. */
|
||||||
if (lang == LANG_BELARUSIAN
|
if (lang == LANG_BELARUSIAN
|
||||||
|
@ -199,7 +345,7 @@ print_all_locales (int verbose)
|
||||||
stpcpy (c, "@cjknarrow");
|
stpcpy (c, "@cjknarrow");
|
||||||
else
|
else
|
||||||
continue;
|
continue;
|
||||||
printlocale (verbose, loc, language, country);
|
add_locale (loc, language, country);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Check Serbian language for the available territories. Up to
|
/* Check Serbian language for the available territories. Up to
|
||||||
|
@ -221,17 +367,19 @@ print_all_locales (int verbose)
|
||||||
sr_RS_idx = i;
|
sr_RS_idx = i;
|
||||||
if (sr_CS_idx > 0 && sr_RS_idx == -1)
|
if (sr_CS_idx > 0 && sr_RS_idx == -1)
|
||||||
{
|
{
|
||||||
printlocale (verbose, "sr_RS@latin",
|
add_locale ("sr_RS@latin", L"Serbian (Latin)", L"Serbia");
|
||||||
L"Serbian (Latin)", L"Serbia");
|
add_locale ("sr_RS", L"Serbian (Cyrillic)", L"Serbia");
|
||||||
printlocale (verbose, "sr_RS",
|
add_locale ("sr_ME@latin", L"Serbian (Latin)", L"Montenegro");
|
||||||
L"Serbian (Cyrillic)", L"Serbia");
|
add_locale ("sr_ME", L"Serbian (Cyrillic)", L"Montenegro");
|
||||||
printlocale (verbose, "sr_ME@latin",
|
|
||||||
L"Serbian (Latin)", L"Montenegro");
|
|
||||||
printlocale (verbose, "sr_ME",
|
|
||||||
L"Serbian (Cyrillic)", L"Montenegro");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* 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]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
Loading…
Reference in New Issue