update_content_info (info, 0, 0);
update_content_info (info, &states[*tocode], 0, 0);
static size_t convert_file_to (FILE *file, const char *fromcode,			       int ncodes, const char **tocodes,			       int *tocode, CONTENT *info){  iconv_t cd1, *cd;  char bufi[256], bufu[512], bufo[4 * sizeof (bufi)];  const char *ib, *ub;  char *ob;  size_t ibl, obl, ubl, ubl1, n, ret;  int i;  CONTENT *infos;  size_t *score;  cd1 = iconv_open ("UTF-8", fromcode);  if (cd1 == (iconv_t)(-1))    return -1;  cd = safe_malloc (ncodes * sizeof (iconv_t));  infos = safe_malloc (ncodes * sizeof (CONTENT));  score = safe_malloc (ncodes * sizeof (size_t));  for (i = 0; i < ncodes; i++)    cd[i] = iconv_open (tocodes[i], "UTF-8");  memset (infos, 0, ncodes * sizeof (CONTENT));  memset (score, 0, ncodes * sizeof (size_t));  rewind (file);  ibl = 0;  for (;;)  {    /* Try to fill input buffer */    n = fread (bufi + ibl, 1, sizeof (bufi) - ibl, file);    ibl += n;    /* Convert to UTF-8 */    ib = bufi;    ob = bufu, obl = sizeof (bufu);    n = iconv (cd1, ibl ? &ib : 0, &ibl, &ob, &obl);    assert (n == (size_t)(-1) || !n || ICONV_NONTRANS);    if (n == (size_t)(-1) &&	((errno != EINVAL && errno != E2BIG) || ib == bufi))    {      assert (errno == EILSEQ ||	      (errno == EINVAL && ib == bufi && ibl < sizeof (bufi)));      ret = (size_t)(-1);      break;    }    ubl1 = ob - bufu;    /* Convert from UTF-8 */    for (i = 0; i < ncodes; i++)      if (cd[i] != (iconv_t)(-1) && score[i] != (size_t)(-1))      {	ub = bufu, ubl = ubl1;	ob = bufo, obl = sizeof (bufo);	n = iconv (cd[i], (ibl || ubl) ? &ub : 0, &ubl, &ob, &obl);	if (n == (size_t)(-1))	{	  assert (errno = E2BIG || (BUGGY_ICONV && errno== EINVAL));	  score[i] = -1;	}	else	{	  score[i] += n;	  update_content_info (&infos[i], bufo, ob - bufo);	}      }    if (ibl)      /* Save unused input */      memmove (bufi, ib, ibl);    else if (!ubl1 && ib < bufi + sizeof (bufi))    {      ret = 0;      break;    }  }  if (!ret)  {    /* Find best score */    ret = (size_t)(-1);    for (i = 0; i < ncodes; i++)    {      if (score[i] == (size_t)(-1))	continue;      if (ret == (size_t)(-1) || score[i] < ret)      {	*tocode = i;	ret = score[i];	if (!ret)	  break;      }    }    if (ret != (size_t)(-1))    {      memcpy (info, &infos[*tocode], sizeof(CONTENT));      update_content_info (info, 0, 0); /* EOF */    }  }  for (i = 0; i < ncodes; i++)    if (cd[i] != (iconv_t)(-1))      iconv_close (cd[i]);  iconv_close (cd1);  free (cd);  free (infos);  free (score);  return ret;}