localcharset.c.diff 2.2 KB

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