gui: Allow File|Open to select an encoding for system files.
[pspp] / src / libpspp / i18n.c
index 1779afc4347ced85aea4b285d5906176c239f12e..cdcf57003bfbd608008314f0c468826e899b19a0 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2006, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
+   Copyright (C) 2006, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -502,7 +502,8 @@ filename_to_utf8 (const char *filename)
    dynamically allocated string in TO-encoding.  Any characters which cannot be
    converted will be represented by '?'.
 
-   The returned string will be null-terminated and allocated on POOL.
+   The returned string will be null-terminated and allocated on POOL with
+   pool_malloc().
 
    This function's behaviour differs from that of g_convert_with_fallback
    provided by GLib.  The GLib function will fail (returns NULL) if any part of
@@ -526,7 +527,11 @@ recode_substring_pool (const char *to, const char *from,
   if ( (iconv_t) -1 == conv )
     {
       struct substring out;
-      ss_alloc_substring_pool (&out, text, pool);
+
+      out.string = pool_malloc (pool, text.length + 1);
+      out.length = text.length;
+      memcpy (out.string, text.string, text.length);
+      out.string[out.length] = '\0';
       return out;
     }
 
@@ -748,6 +753,39 @@ utf8_strncasecmp (const char *a, size_t an, const char *b, size_t bn)
 
   return result;
 }
+
+static char *
+utf8_casemap (const char *s,
+              uint8_t *(*f) (const uint8_t *, size_t, const char *, uninorm_t,
+                             uint8_t *, size_t *))
+{
+  char *result;
+  size_t size;
+
+  result = CHAR_CAST (char *,
+                      f (CHAR_CAST (const uint8_t *, s), strlen (s) + 1,
+                         NULL, NULL, NULL, &size));
+  if (result == NULL)
+    {
+      if (errno == ENOMEM)
+        xalloc_die ();
+
+      result = xstrdup (s);
+    }
+  return result;
+}
+
+char *
+utf8_to_upper (const char *s)
+{
+  return utf8_casemap (s, u8_toupper);
+}
+
+char *
+utf8_to_lower (const char *s)
+{
+  return utf8_casemap (s, u8_tolower);
+}
 \f
 bool
 get_encoding_info (struct encoding_info *e, const char *name)