OSDN Git Service

* getlocale.c (usage): Change text slightly.
[pf3gnuchains/pf3gnuchains4x.git] / winsup / utils / getlocale.c
1 /*
2  * Copyright (c) 2010, Corinna Vinschen
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26 #include <stdio.h>
27 #include <getopt.h>
28 #include <string.h>
29 #include <wchar.h>
30 #include <locale.h>
31 #define WINVER 0x0601
32 #include <windows.h>
33
34 extern char *__progname;
35
36 void usage (FILE *, int) __attribute__ ((noreturn));
37
38 void
39 usage (FILE * stream, int status)
40 {
41   fprintf (stream,
42            "Usage: %s [-asuh]\n"
43            "Print default locale or list of all supported locales\n"
44            "\n"
45            "Options:\n"
46            "\n"
47            "  -a, --all       List all available supported locales\n"
48            "  -s, --system    Print system default locale\n"
49            "                  (default is current user default locale)\n"
50            "  -u, --utf       Attach \".UTF-8\" to the result\n"
51            "  -h, --help      this text\n",
52            __progname);
53   exit (status);
54 }
55
56 struct option longopts[] = {
57   {"all", no_argument, NULL, 'a'},
58   {"system", no_argument, NULL, 's'},
59   {"utf", no_argument, NULL, 'u'},
60   {"help", no_argument, NULL, 'h'},
61   {0, no_argument, NULL, 0}
62 };
63 const char *opts = "ahsu";
64
65 int
66 getlocale (LCID lcid, char *name)
67 {
68   char iso639[10];
69   char iso3166[10];
70
71   iso3166[0] = '\0';
72   if (!GetLocaleInfo (lcid, LOCALE_SISO639LANGNAME, iso639, 10))
73     return 0;
74   GetLocaleInfo (lcid, LOCALE_SISO3166CTRYNAME, iso3166, 10);
75   sprintf (name, "%s%s%s", iso639, lcid > 0x3ff ? "_" : "",
76                            lcid > 0x3ff ? iso3166 : "");
77   return 1;
78 }
79
80 int main (int argc, char **argv)
81 {
82   int opt;
83   LCID lcid = LOCALE_USER_DEFAULT;
84   int all = 0;
85   const char *utf = "";
86   char name[32];
87
88   setlocale (LC_ALL, "");
89   while ((opt = getopt_long (argc, argv, opts, longopts, NULL)) != EOF)
90     switch (opt)
91       {
92       case 'a':
93         all = 1;
94         break;
95       case 's':
96         lcid = LOCALE_SYSTEM_DEFAULT;
97         break;
98       case 'u':
99         utf = ".UTF-8";
100         break;
101       case 'h':
102         usage (stdout, 0);
103         break;
104       default:
105         usage (stderr, 1);
106         break;
107       }
108   if (all)
109     {
110       unsigned lang, sublang;
111
112       for (lang = 1; lang <= 0xff; ++lang)
113         {
114           struct {
115             wchar_t lang[256];
116             wchar_t country[256];
117             char loc[32];
118           } loc_list[32];
119           int lcnt = 0;
120
121           for (sublang = 1; sublang <= 0x3f; ++sublang)
122             {
123               lcid = (sublang << 10) | lang;
124               if (getlocale (lcid, name))
125                 {
126                   wchar_t lang[256];
127                   wchar_t country[256];
128                   int i;
129                   char *c, loc[32];
130                   wchar_t wbuf[9];
131
132                   /* Go figure.  Even the English name of a language or
133                      locale might contain native characters. */
134                   GetLocaleInfoW (lcid, LOCALE_SENGLANGUAGE, lang, 256);
135                   GetLocaleInfoW (lcid, LOCALE_SENGCOUNTRY, country, 256);
136                   /* Avoid dups */
137                   for (i = 0; i < lcnt; ++ i)
138                     if (!wcscmp (loc_list[i].lang, lang)
139                         && !wcscmp (loc_list[i].country, country))
140                       break;
141                   if (i < lcnt)
142                     continue;
143                   if (lcnt < 32)
144                     {
145                       wcscpy (loc_list[lcnt].lang, lang);
146                       wcscpy (loc_list[lcnt].country, country);
147                     }
148                   /* Now check certain conditions to figure out if that
149                      locale requires a modifier. */
150                   c = stpcpy (loc, name);
151                   if (wcsstr (lang, L"(Latin)")
152                       && (!strncmp (loc, "sr_", 3)
153                           || !strcmp (loc, "be_BY")))
154                     stpcpy (c, "@latin");
155                   else if (wcsstr (lang, L"(Cyrillic)")
156                            && !strcmp (loc, "uz_UZ"))
157                     stpcpy (c, "@cyrillic");
158                   /* Avoid more dups */
159                   for (i = 0; i < lcnt; ++ i)
160                     if (!strcmp (loc_list[i].loc, loc))
161                       {
162                         lcnt++;
163                         break;
164                       }
165                   if (i < lcnt)
166                     continue;
167                   if (lcnt < 32)
168                     strcpy (loc_list[lcnt++].loc, loc);
169                   /* Print */
170                   printf ("%-16s %ls (%ls)\n", loc, lang, country);
171                   /* Check for locales which sport a modifier for
172                      changing the codeset and other stuff. */
173                   if (!strcmp (loc, "tt_RU"))
174                     stpcpy (c, "@iqtelif");
175                   else if (GetLocaleInfoW (lcid, LOCALE_SINTLSYMBOL, wbuf, 9)
176                            && !wcsncmp (wbuf, L"EUR", 3))
177                     stpcpy (c, "@euro");
178                   else if (!strncmp (loc, "ja_", 3)
179                            || !strncmp (loc, "ko_", 3)
180                            || !strncmp (loc, "zh_", 3))
181                     stpcpy (c, "@cjknarrow");
182                   else
183                     continue;
184                   printf ("%-16s %ls (%ls)\n", loc, lang, country);
185                 }
186             }
187         }
188       return 0;
189     }
190   if (getlocale (lcid, name))
191     printf ("%s%s\n", name, utf);
192   return 0;
193 }