int cost;
int cost_hi;
add_module (char *rp, const char *directory, size_t dir_len, void **modules,	    size_t *nmodules){  /* We expect now     1. `from' name     2. `to' name     3. filename of the module     4. an optional cost value  */  struct gconv_module *new_module;  char *from, *to, *module, *wp;  size_t const_len;  int from_is_regex;  int need_ext;  int cost;  while (isspace (*rp))    ++rp;  from = rp;  from_is_regex = 0;  while (*rp != '\0' && !isspace (*rp))    {      if (!isalnum (*rp) && *rp != '-' && *rp != '/' && *rp != '.'	  && *rp != '_')	from_is_regex = 1;      ++rp;    }  if (*rp == '\0')    return;  *rp++ = '\0';  to = wp = rp;  while (isspace (*rp))    ++rp;  while (*rp != '\0' && !isspace (*rp))    *wp++ = *rp++;  if (*rp == '\0')    return;  *wp++ = '\0';  do    ++rp;  while (isspace (*rp));  module = wp;  while (*rp != '\0' && !isspace (*rp))    *wp++ = *rp++;  if (*rp == '\0')    {      /* There is no cost, use one by default.  */      *wp++ = '\0';      cost = 1;    }  else    {      /* There might be a cost value.  */      char *endp;      *wp++ = '\0';      cost = strtol (rp, &endp, 10);      if (rp == endp)	/* No useful information.  */	cost = 1;    }  if (module[0] == '\0')    /* No module name given.  */    return;  if (module[0] == '/')    dir_len = 0;  else    /* Increment by one for the slash.  */    ++dir_len;  /* See whether we must add the ending.  */  need_ext = 0;  if (wp - module < sizeof (gconv_module_ext)      || memcmp (wp - sizeof (gconv_module_ext), gconv_module_ext,		 sizeof (gconv_module_ext)) != 0)    /* We must add the module extension.  */    need_ext = sizeof (gconv_module_ext) - 1;  /* We've collected all the information, now create an entry.  */  if (from_is_regex)    {      const_len = 0;      while (isalnum (from[const_len]) || from[const_len] == '-'	     || from[const_len] == '/' || from[const_len] == '.'	     || from[const_len] == '_')	++const_len;    }  else    const_len = to - from - 1;  new_module = (struct gconv_module *) malloc (sizeof (struct gconv_module)					       + (wp - from)					       + dir_len + need_ext);  if (new_module != NULL)    {      char *tmp;      new_module->from_constpfx = memcpy ((char *) new_module					  + sizeof (struct gconv_module),					  from, to - from);      if (from_is_regex)	new_module->from_pattern = new_module->from_constpfx;      else	new_module->from_pattern = NULL;      new_module->from_constpfx_len = const_len;      new_module->from_regex = NULL;      new_module->to_string = memcpy ((char *) new_module->from_constpfx				      + (to - from), to, module - to);      new_module->cost = cost;      new_module->module_name = (char *) new_module->to_string + (module - to);      if (dir_len == 0)	tmp = (char *) new_module->module_name;      else	{	  tmp = __mempcpy ((char *) new_module->module_name,			   directory, dir_len - 1);	  *tmp++ = '/';	}      tmp = __mempcpy (tmp, module, wp - module);      if (need_ext)	memcpy (tmp - 1, gconv_module_ext, sizeof (gconv_module_ext));      if (__tfind (new_module, modules, module_compare) == NULL)	if (__tsearch (new_module, modules, module_compare) == NULL)	  /* Something went wrong while inserting the new module.  */	  free (new_module);	else	  ++*nmodules;    }}