Commit | Line | Data |
---|---|---|
c2c2b5a4 LC |
1 | Add a variant of `locale_charset' that returns its result based solely on |
2 | information from the environment. See | |
3 | http://lists.gnu.org/archive/html/guile-devel/2011-11/msg00040.html for the | |
4 | rationale. | |
5 | ||
005de2e8 LC |
6 | --- a/lib/localcharset.c |
7 | +++ b/lib/localcharset.c | |
8 | @@ -544,3 +544,73 @@ locale_charset (void) | |
c2c2b5a4 | 9 | |
5de00531 LC |
10 | return codeset; |
11 | } | |
c2c2b5a4 LC |
12 | + |
13 | +/* A variant of the above, without calls to `setlocale', `nl_langinfo', | |
14 | + etc. */ | |
15 | +const char * | |
16 | +environ_locale_charset (void) | |
17 | +{ | |
18 | + static char buf[2 + 10 + 1]; | |
19 | + const char *codeset, *aliases; | |
20 | + const char *locale = NULL; | |
21 | + | |
22 | + locale = getenv ("LC_ALL"); | |
23 | + if (locale == NULL || locale[0] == '\0') | |
24 | + { | |
25 | + locale = getenv ("LC_CTYPE"); | |
26 | + if (locale == NULL || locale[0] == '\0') | |
27 | + locale = getenv ("LANG"); | |
28 | + } | |
29 | + | |
30 | + if (locale != NULL && locale[0] != '\0') | |
31 | + { | |
32 | + /* If the locale name contains an encoding after the dot, return it. */ | |
33 | + const char *dot = strchr (locale, '.'); | |
34 | + | |
35 | + if (dot != NULL) | |
36 | + { | |
37 | + const char *modifier; | |
38 | + | |
39 | + dot++; | |
40 | + /* Look for the possible @... trailer and remove it, if any. */ | |
41 | + modifier = strchr (dot, '@'); | |
42 | + if (modifier == NULL) | |
43 | + return dot; | |
44 | + if (modifier - dot < sizeof (buf)) | |
45 | + { | |
46 | + memcpy (buf, dot, modifier - dot); | |
47 | + buf [modifier - dot] = '\0'; | |
48 | + return buf; | |
49 | + } | |
50 | + } | |
51 | + else if (strcmp (locale, "C") == 0) | |
52 | + { | |
53 | + strcpy (buf, "ASCII"); | |
54 | + return buf; | |
55 | + } | |
5de00531 LC |
56 | + else |
57 | + codeset = ""; | |
c2c2b5a4 LC |
58 | + } |
59 | + else | |
60 | + codeset = ""; | |
61 | + | |
62 | + /* Resolve alias. */ | |
5de00531 LC |
63 | + for (aliases = get_charset_aliases (); |
64 | + *aliases != '\0'; | |
65 | + aliases += strlen (aliases) + 1, aliases += strlen (aliases) + 1) | |
66 | + if (strcmp (codeset, aliases) == 0 | |
67 | + || (aliases[0] == '*' && aliases[1] == '\0')) | |
68 | + { | |
69 | + codeset = aliases + strlen (aliases) + 1; | |
70 | + break; | |
71 | + } | |
72 | + | |
73 | + /* Don't return an empty string. GNU libc and GNU libiconv interpret | |
74 | + the empty string as denoting "the locale's character encoding", | |
75 | + thus GNU libiconv would call this function a second time. */ | |
76 | + if (codeset[0] == '\0') | |
77 | + /* Default to Latin-1, for backward compatibility with Guile 1.8. */ | |
78 | + codeset = "ISO-8859-1"; | |
79 | + | |
80 | + return codeset; | |
81 | +} |