Annotation of src/usr.bin/locale/locale.c, Revision 1.8
1.8 ! millert 1: /* $OpenBSD: locale.c,v 1.7 2013/11/13 20:44:21 deraadt Exp $ */
1.1 stsp 2: /*
3: * Copyright (c) 2013 Stefan Sperling <stsp@openbsd.org>
4: *
5: * Permission to use, copy, modify, and distribute this software for any
6: * purpose with or without fee is hereby granted, provided that the above
7: * copyright notice and this permission notice appear in all copies.
8: *
9: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16: */
17:
18: #include <stdio.h>
19: #include <stdlib.h>
20: #include <string.h>
21: #include <locale.h>
1.8 ! millert 22: #include <unistd.h>
1.1 stsp 23:
24: extern char *__progname;
25:
26: struct category_name {
27: int category;
28: const char *name;
29: } categories[] = {
30: { LC_COLLATE, "LC_COLLATE" },
31: { LC_CTYPE, "LC_CTYPE" },
32: { LC_MONETARY, "LC_MONETARY" },
33: { LC_NUMERIC, "LC_NUMERIC" },
34: { LC_TIME, "LC_TIME" },
35: { LC_MESSAGES, "LC_MESSAGES" },
36: { 0, NULL},
37: };
38:
1.7 deraadt 39: static void
1.5 guenther 40: put_assignment(const char *name, const char *value, int double_quoted)
41: {
42: char c;
43:
44: fputs(name, stdout);
45: putchar('=');
46: if (double_quoted)
47: putchar('"');
48: if (value != NULL)
49: while ((c = *value++) != '\0')
50: switch (c) {
51: case ' ': case '\t': case '\n': case '\'':
52: case '(': case ')': case '<': case '>':
53: case '&': case ';': case '|': case '~':
54: if (!double_quoted)
55: case '"': case '\\': case '$': case '`':
56: putchar('\\');
57: default:
58: putchar(c);
59: break;
60: }
61: if (double_quoted)
62: putchar('"');
63: putchar('\n');
64: }
65:
1.7 deraadt 66: static void
67: show_current_locale(void)
1.1 stsp 68: {
1.3 jca 69: char *lang, *lc_all;
1.1 stsp 70: int i;
71:
1.3 jca 72: lang = getenv("LANG");
73: lc_all = getenv("LC_ALL");
74:
1.5 guenther 75: put_assignment("LANG", lang, 0);
1.3 jca 76: for (i = 0; categories[i].name != NULL; i++) {
77: if (lc_all == NULL && getenv(categories[i].name))
1.5 guenther 78: put_assignment(categories[i].name,
79: getenv(categories[i].name), 0);
1.3 jca 80: else
1.5 guenther 81: put_assignment(categories[i].name,
82: setlocale(categories[i].category, NULL), 1);
1.3 jca 83: }
1.5 guenther 84: put_assignment("LC_ALL", lc_all, 0);
1.1 stsp 85: }
86:
87: const char * const some_locales[] = {
88: "C",
89: "C.UTF-8",
90: "POSIX",
91: "POSIX.UTF-8",
1.4 jca 92: "Pig.ISO8859-1",
93: "Pig.UTF-8",
1.1 stsp 94: "ar_SD.UTF-8",
95: "ar_SY.UTF-8",
96: "bg_BG.CP1251",
97: "ca_ES.ISO8859-1",
98: "ca_ES.ISO8859-15",
99: "ca_ES.UTF-8",
100: "cs_CZ.ISO8859-2",
101: "cs_CZ.UTF-8",
102: "da_DK.ISO8859-1",
103: "da_DK.ISO8859-15",
104: "da_DK.UTF-8",
105: "de_AT.ISO8859-1",
106: "de_AT.ISO8859-15",
107: "de_AT.UTF-8",
108: "de_CH.ISO8859-1",
109: "de_CH.ISO8859-15",
110: "de_CH.UTF-8",
111: "de_DE.ISO8859-1",
112: "de_DE.ISO8859-15",
113: "de_DE.UTF-8",
114: "el_GR.ISO8859-7",
115: "el_GR.UTF-8",
116: "en_AU.ISO8859-1",
117: "en_AU.ISO8859-15",
118: "en_AU.UTF-8",
119: "en_CA.ISO8859-1",
120: "en_CA.ISO8859-15",
121: "en_CA.UTF-8",
122: "en_GB.ISO8859-1",
123: "en_GB.ISO8859-15",
124: "en_GB.UTF-8",
125: "en_US.ISO8859-1",
126: "en_US.ISO8859-15",
127: "en_US.UTF-8",
128: "es_AR.ISO8859-1",
129: "es_AR.ISO8859-15",
130: "es_AR.UTF-8",
131: "es_BO.ISO8859-1",
132: "es_BO.ISO8859-15",
133: "es_BO.UTF-8",
134: "es_CH.ISO8859-1",
135: "es_CH.ISO8859-15",
136: "es_CH.UTF-8",
137: "es_CO.ISO8859-1",
138: "es_CO.ISO8859-15",
139: "es_CO.UTF-8",
140: "es_CR.ISO8859-1",
141: "es_CR.ISO8859-15",
142: "es_CR.UTF-8",
143: "es_CU.ISO8859-1",
144: "es_CU.ISO8859-15",
145: "es_CU.UTF-8",
146: "es_DO.ISO8859-1",
147: "es_DO.ISO8859-15",
148: "es_DO.UTF-8",
149: "es_EC.ISO8859-1",
150: "es_EC.ISO8859-15",
151: "es_EC.UTF-8",
152: "es_ES.ISO8859-1",
153: "es_ES.ISO8859-15",
154: "es_ES.UTF-8",
155: "es_GQ.ISO8859-1",
156: "es_GQ.ISO8859-15",
157: "es_GQ.UTF-8",
158: "es_GT.ISO8859-1",
159: "es_GT.ISO8859-15",
160: "es_GT.UTF-8",
161: "es_HN.ISO8859-1",
162: "es_HN.ISO8859-15",
163: "es_HN.UTF-8",
164: "es_MX.ISO8859-1",
165: "es_MX.ISO8859-15",
166: "es_MX.UTF-8",
167: "es_NI.ISO8859-1",
168: "es_NI.ISO8859-15",
169: "es_NI.UTF-8",
170: "es_PA.ISO8859-1",
171: "es_PA.ISO8859-15",
172: "es_PA.UTF-8",
173: "es_PE.ISO8859-1",
174: "es_PE.ISO8859-15",
175: "es_PE.UTF-8",
176: "es_PR.ISO8859-1",
177: "es_PR.ISO8859-15",
178: "es_PR.UTF-8",
179: "es_PY.ISO8859-1",
180: "es_PY.ISO8859-15",
181: "es_PY.UTF-8",
182: "es_SV.ISO8859-1",
183: "es_SV.ISO8859-15",
184: "es_SV.UTF-8",
185: "es_US.ISO8859-1",
186: "es_US.ISO8859-15",
187: "es_US.UTF-8",
188: "es_UY.ISO8859-1",
189: "es_UY.ISO8859-15",
190: "es_UY.UTF-8",
191: "es_VE.ISO8859-1",
192: "es_VE.ISO8859-15",
193: "es_VE.UTF-8",
194: "fa_IR.UTF-8",
195: "fi_FI.ISO8859-1",
196: "fi_FI.ISO8859-15",
197: "fi_FI.UTF-8",
198: "fr_BE.ISO8859-1",
199: "fr_BE.ISO8859-15",
200: "fr_BE.UTF-8",
201: "fr_CA.ISO8859-1",
202: "fr_CA.ISO8859-15",
203: "fr_CA.UTF-8",
204: "fr_CH.ISO8859-1",
205: "fr_CH.ISO8859-15",
206: "fr_CH.UTF-8",
207: "fr_FR.ISO8859-1",
208: "fr_FR.ISO8859-15",
209: "fr_FR.UTF-8",
210: "hr_HR.ISO8859-2",
211: "hu_HU.ISO8859-2",
212: "hu_HU.UTF-8",
213: "hy_AM.ARMSCII-8",
214: "hy_AM.UTF-8",
215: "is_IS.ISO8859-1",
216: "is_IS.ISO8859-15",
217: "is_IS.UTF-8",
218: "it_CH.ISO8859-1",
219: "it_CH.ISO8859-15",
220: "it_CH.UTF-8",
221: "it_IT.ISO8859-1",
222: "it_IT.ISO8859-15",
223: "it_IT.UTF-8",
224: "ja_JP.UTF-8",
225: "ko_KR.UTF-8",
226: "lt_LT.ISO8859-13",
227: "lt_LT.ISO8859-4",
228: "lt_LT.UTF-8",
229: "nl_BE.ISO8859-1",
230: "nl_BE.ISO8859-15",
231: "nl_BE.UTF-8",
232: "nl_NL.ISO8859-1",
233: "nl_NL.ISO8859-15",
234: "nl_NL.UTF-8",
235: "no_NO.ISO8859-1",
236: "no_NO.ISO8859-15",
237: "no_NO.UTF-8",
238: "pl_PL.ISO8859-2",
239: "pl_PL.UTF-8",
240: "pt_PT.ISO8859-1",
241: "pt_PT.ISO8859-15",
242: "pt_PT.UTF-8",
243: "ro_RO.UTF-8",
244: "ru_RU.CP866",
245: "ru_RU.ISO8859-5",
246: "ru_RU.KOI8-R",
247: "ru_RU.UTF-8",
248: "sk_SK.ISO8859-2",
249: "sk_SK.UTF-8",
250: "sl_SI.ISO8859-2",
251: "sl_SI.UTF-8",
252: "sv_SE.ISO8859-1",
253: "sv_SE.ISO8859-15",
254: "sv_SE.UTF-8",
1.6 fgsch 255: "tr_TR.ISO8859-9",
256: "tr_TR.UTF-8",
1.1 stsp 257: "uk_UA.KOI8-U",
258: "uk_UA.UTF-8",
259: "zh_CN.UTF-8",
260: "zh_TW.UTF-8",
261: NULL
262: };
263:
1.7 deraadt 264: static void
1.1 stsp 265: show_locales(void)
266: {
267: int i = 0;
268:
269: while (some_locales[i])
270: puts(some_locales[i++]);
271: }
272:
1.7 deraadt 273: static void
1.1 stsp 274: show_charsets(void)
275: {
276: char *charset;
277: char charsets[sizeof(LOCALE_CHARSETS)];
278: char *s = charsets;
279:
280: bcopy(LOCALE_CHARSETS, charsets, sizeof(charsets));
281: do {
282: charset = strsep(&s, " \t");
283: if (charset && charset[0])
284: printf("%s\n", charset);
285: } while (charset);
286: }
287:
1.7 deraadt 288: static void
1.1 stsp 289: usage(void)
290: {
291: fprintf(stderr, "usage: %s [-a | -m]\n", __progname);
292: exit(1);
293: }
294:
295: int
296: main(int argc, char *argv[])
297: {
298: int opt, aflag = 0, mflag = 0;
299:
300: setlocale(LC_ALL, "");
301:
302: if (argc == 1) {
303: show_current_locale();
304: return 0;
305: }
306:
307: while ((opt = getopt(argc, argv, "am")) != -1) {
308: switch (opt) {
309: case 'a':
310: aflag = 1;
311: break;
312: case 'm':
313: mflag = 1;
314: break;
315: default:
316: usage();
317: }
318: }
319: argc -= optind;
320: argv += optind;
321:
322: if (argc != 0 || (aflag && mflag))
323: usage();
324: else if (aflag)
325: show_locales();
326: else if (mflag)
327: show_charsets();
328:
329: return 0;
330: }