summaryrefslogtreecommitdiff
path: root/gnulib-local/lib/localcharset.c.diff
blob: 2b27ee47911813394e0f219b02e9e7507a891089 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
Add a variant of `locale_charset' that returns its result based solely on
information from the environment.  See
http://lists.gnu.org/archive/html/guile-devel/2011-11/msg00040.html for the
rationale.

--- a/lib/localcharset.c	2011-12-14 23:10:58.000000000 +0100
+++ b/lib/localcharset.c	2011-12-15 00:45:12.000000000 +0100
@@ -527,6 +527,76 @@ locale_charset (void)
     codeset = "";
 
   /* Resolve alias. */
+  for (aliases = get_charset_aliases ();
+       *aliases != '\0';
+       aliases += strlen (aliases) + 1, aliases += strlen (aliases) + 1)
+    if (strcmp (codeset, aliases) == 0
+        || (aliases[0] == '*' && aliases[1] == '\0'))
+      {
+        codeset = aliases + strlen (aliases) + 1;
+        break;
+      }
+
+  /* Don't return an empty string.  GNU libc and GNU libiconv interpret
+     the empty string as denoting "the locale's character encoding",
+     thus GNU libiconv would call this function a second time.  */
+  if (codeset[0] == '\0')
+    codeset = "ASCII";
+
+  return codeset;
+}
+
+/* A variant of the above, without calls to `setlocale', `nl_langinfo',
+   etc.  */
+const char *
+environ_locale_charset (void)
+{
+  static char buf[2 + 10 + 1];
+  const char *codeset, *aliases;
+  const char *locale = NULL;
+
+  locale = getenv ("LC_ALL");
+  if (locale == NULL || locale[0] == '\0')
+    {
+      locale = getenv ("LC_CTYPE");
+      if (locale == NULL || locale[0] == '\0')
+	locale = getenv ("LANG");
+    }
+
+  if (locale != NULL && locale[0] != '\0')
+    {
+      /* If the locale name contains an encoding after the dot, return it.  */
+      const char *dot = strchr (locale, '.');
+
+      if (dot != NULL)
+        {
+          const char *modifier;
+
+          dot++;
+          /* Look for the possible @... trailer and remove it, if any.  */
+          modifier = strchr (dot, '@');
+          if (modifier == NULL)
+            return dot;
+          if (modifier - dot < sizeof (buf))
+            {
+              memcpy (buf, dot, modifier - dot);
+              buf [modifier - dot] = '\0';
+              return buf;
+            }
+        }
+      else if (strcmp (locale, "C") == 0)
+	{
+	  strcpy (buf, "ASCII");
+	  return buf;
+	}
+
+      /* Resolve through the charset.alias file.  */
+      codeset = locale;
+    }
+  else
+    codeset = "";
+
+  /* Resolve alias. */
   for (aliases = get_charset_aliases ();
        *aliases != '\0';
        aliases += strlen (aliases) + 1, aliases += strlen (aliases) + 1)