(tests): Add tst-iconv2.
[kopensolaris-gnu/glibc.git] / iconv / gconv_conf.c
index 4746f43..b7e7692 100644 (file)
@@ -23,6 +23,7 @@
 #include <errno.h>
 #include <limits.h>
 #include <search.h>
+#include <stddef.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -38,7 +39,7 @@ static const char default_gconv_path[] = GCONV_PATH;
 
 /* The path elements, as determined by the __gconv_get_path function.
    All path elements end in a slash.  */
-const struct path_elem *__gconv_path_elem;
+struct path_elem *__gconv_path_elem;
 /* Maximum length of a single path element in __gconv_path_elem.  */
 size_t __gconv_max_path_elem_len;
 
@@ -195,8 +196,20 @@ insert_module (struct gconv_module *newp, int tobefreed)
 
          if (root != NULL)
            {
-             /* This is a no new conversion.  */
-             if (tobefreed)
+             /* This is a no new conversion.  But maybe the cost is
+                better.  */
+             if (newp->cost_hi < root->cost_hi
+                 || (newp->cost_hi == root->cost_hi
+                     && newp->cost_lo < root->cost_lo))
+               {
+                 newp->left = root->left;
+                 newp->right = root->right;
+                 newp->same = root->same;
+                 *rootp = newp;
+
+                 free (root);
+               }
+             else if (tobefreed)
                free (newp);
              return;
            }
@@ -283,7 +296,7 @@ add_module (char *rp, const char *directory, size_t dir_len, void **modules,
 
   /* See whether we must add the ending.  */
   need_ext = 0;
-  if (wp - module < sizeof (gconv_module_ext)
+  if (wp - module < (ptrdiff_t) sizeof (gconv_module_ext)
       || memcmp (wp - sizeof (gconv_module_ext), gconv_module_ext,
                 sizeof (gconv_module_ext)) != 0)
     /* We must add the module extension.  */
@@ -304,23 +317,19 @@ add_module (char *rp, const char *directory, size_t dir_len, void **modules,
     {
       char *tmp;
 
-      new_module->from_string = memcpy ((char *) new_module
-                                       + sizeof (struct gconv_module),
-                                       from, to - from);
+      new_module->from_string = tmp = (char *) (new_module + 1);
+      tmp = __mempcpy (tmp, from, to - from);
 
-      new_module->to_string = memcpy ((char *) new_module->from_string
-                                     + (to - from), to, module - to);
+      new_module->to_string = tmp;
+      tmp = __mempcpy (tmp, to, module - to);
 
       new_module->cost_hi = cost_hi;
       new_module->cost_lo = modcounter;
 
-      new_module->module_name = (char *) new_module->to_string + (module - to);
+      new_module->module_name = tmp;
 
-      if (dir_len == 0)
-       tmp = (char *) new_module->module_name;
-      else
-       tmp = __mempcpy ((char *) new_module->module_name,
-                        directory, dir_len);
+      if (dir_len != 0)
+       tmp = __mempcpy (tmp, directory, dir_len);
 
       tmp = __mempcpy (tmp, module, wp - module);
 
@@ -342,7 +351,7 @@ read_conf_file (const char *filename, const char *directory, size_t dir_len,
   FILE *fp = fopen (filename, "r");
   char *line = NULL;
   size_t line_len = 0;
-  int modcounter = 0;
+  static int modcounter;
 
   /* Don't complain if a file is not present or readable, simply silently
      ignore it.  */
@@ -420,7 +429,7 @@ __gconv_get_path (void)
       char *cwd;
       size_t cwdlen;
 
-      user_path = __secure_getenv ("GCONV_PATH");
+      user_path = getenv ("GCONV_PATH");
       if (user_path == NULL)
        {
          /* No user-defined path.  Make a modifiable copy of the