File: [local] / src / usr.bin / locale / locale.c (download)
Revision 1.13, Fri Apr 17 10:45:04 2020 UTC (4 years, 1 month ago) by schwarze
Branch: MAIN
CVS Tags: OPENBSD_7_5_BASE, OPENBSD_7_5, OPENBSD_7_4_BASE, OPENBSD_7_4, OPENBSD_7_3_BASE, OPENBSD_7_3, OPENBSD_7_2_BASE, OPENBSD_7_2, OPENBSD_7_1_BASE, OPENBSD_7_1, OPENBSD_7_0_BASE, OPENBSD_7_0, OPENBSD_6_9_BASE, OPENBSD_6_9, OPENBSD_6_8_BASE, OPENBSD_6_8, OPENBSD_6_7_BASE, OPENBSD_6_7, HEAD Changes since 1.12: +8 -3 lines
implement the "charmap" argument as required by POSIX;
OK stsp@ millert@
|
/* $OpenBSD: locale.c,v 1.13 2020/04/17 10:45:04 schwarze Exp $ */
/*
* Copyright (c) 2013 Stefan Sperling <stsp@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <err.h>
#include <langinfo.h>
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
extern char *__progname;
struct category_name {
int category;
const char *name;
} categories[] = {
{ LC_COLLATE, "LC_COLLATE" },
{ LC_CTYPE, "LC_CTYPE" },
{ LC_MONETARY, "LC_MONETARY" },
{ LC_NUMERIC, "LC_NUMERIC" },
{ LC_TIME, "LC_TIME" },
{ LC_MESSAGES, "LC_MESSAGES" },
{ 0, NULL},
};
static void
put_assignment(const char *name, const char *value, int double_quoted)
{
char c;
fputs(name, stdout);
putchar('=');
if (double_quoted)
putchar('"');
if (value != NULL)
while ((c = *value++) != '\0')
switch (c) {
case ' ': case '\t': case '\n': case '\'':
case '(': case ')': case '<': case '>':
case '&': case ';': case '|': case '~':
if (!double_quoted)
case '"': case '\\': case '$': case '`':
putchar('\\');
default:
putchar(c);
break;
}
if (double_quoted)
putchar('"');
putchar('\n');
}
static void
show_current_locale(void)
{
char *lang, *lc_all;
int i;
lang = getenv("LANG");
lc_all = getenv("LC_ALL");
put_assignment("LANG", lang, 0);
for (i = 0; categories[i].name != NULL; i++) {
if (lc_all == NULL && getenv(categories[i].name))
put_assignment(categories[i].name,
getenv(categories[i].name), 0);
else
put_assignment(categories[i].name,
setlocale(categories[i].category, NULL), 1);
}
put_assignment("LC_ALL", lc_all, 0);
}
const char * const some_locales[] = {
"C",
"C.UTF-8",
"POSIX",
"POSIX.UTF-8",
"Pig.UTF-8",
"ar_SD.UTF-8",
"ar_SY.UTF-8",
"ca_ES.UTF-8",
"cs_CZ.UTF-8",
"da_DK.UTF-8",
"de_AT.UTF-8",
"de_CH.UTF-8",
"de_DE.UTF-8",
"el_GR.UTF-8",
"en_AU.UTF-8",
"en_CA.UTF-8",
"en_GB.UTF-8",
"en_US.UTF-8",
"es_AR.UTF-8",
"es_BO.UTF-8",
"es_CH.UTF-8",
"es_CO.UTF-8",
"es_CR.UTF-8",
"es_CU.UTF-8",
"es_DO.UTF-8",
"es_EC.UTF-8",
"es_ES.UTF-8",
"es_GQ.UTF-8",
"es_GT.UTF-8",
"es_HN.UTF-8",
"es_MX.UTF-8",
"es_NI.UTF-8",
"es_PA.UTF-8",
"es_PE.UTF-8",
"es_PR.UTF-8",
"es_PY.UTF-8",
"es_SV.UTF-8",
"es_US.UTF-8",
"es_UY.UTF-8",
"es_VE.UTF-8",
"fa_IR.UTF-8",
"fi_FI.UTF-8",
"fr_BE.UTF-8",
"fr_CA.UTF-8",
"fr_CH.UTF-8",
"fr_FR.UTF-8",
"hu_HU.UTF-8",
"hy_AM.UTF-8",
"is_IS.UTF-8",
"it_CH.UTF-8",
"it_IT.UTF-8",
"ja_JP.UTF-8",
"ko_KR.UTF-8",
"lt_LT.UTF-8",
"nl_BE.UTF-8",
"nl_NL.UTF-8",
"no_NO.UTF-8",
"pl_PL.UTF-8",
"pt_PT.UTF-8",
"ro_RO.UTF-8",
"ru_RU.UTF-8",
"sk_SK.UTF-8",
"sl_SI.UTF-8",
"sv_SE.UTF-8",
"tr_TR.UTF-8",
"uk_UA.UTF-8",
"zh_CN.UTF-8",
"zh_TW.UTF-8",
NULL
};
static void
show_locales(void)
{
int i = 0;
while (some_locales[i])
puts(some_locales[i++]);
}
static void
usage(void)
{
fprintf(stderr, "usage: %s [-a | -m | charmap]\n", __progname);
exit(1);
}
int
main(int argc, char *argv[])
{
int opt, aflag = 0, mflag = 0;
setlocale(LC_ALL, "");
if (pledge("stdio", NULL) == -1)
err(1, "pledge");
if (argc == 1) {
show_current_locale();
return 0;
}
while ((opt = getopt(argc, argv, "am")) != -1) {
switch (opt) {
case 'a':
aflag = 1;
break;
case 'm':
mflag = 1;
break;
default:
usage();
}
}
argc -= optind;
argv += optind;
if (aflag + mflag + argc > 1)
usage();
else if (aflag)
show_locales();
else if (mflag)
printf("UTF-8\n");
else if (strcmp(*argv, "charmap") == 0)
printf("%s\n", nl_langinfo(CODESET));
else
usage();
return 0;
}