/* Message list concatenation and duplicate handling.
   Copyright (C) 2001-2003, 2005-2008, 2012, 2015, 2019-2021 Free Software
   Foundation, Inc.
   Written by Bruno Haible <haible@clisp.cons.org>, 2001.

   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
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */


#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <alloca.h>

/* Specification.  */
#include "msgl-cat.h"

#include <limits.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>

#include "error.h"
#include "xerror.h"
#include "xvasprintf.h"
#include "message.h"
#include "read-catalog.h"
#include "po-charset.h"
#include "msgl-ascii.h"
#include "msgl-ofn.h"
#include "msgl-equal.h"
#include "msgl-iconv.h"
#include "xalloc.h"
#include "xmalloca.h"
#include "c-strstr.h"
#include "basename-lgpl.h"
#include "gettext.h"

#define _(str) gettext (str)


/* These variables control which messages are selected.  */
int more_than;
int less_than;

/* If true, use the first available translation.
   If false, merge all available translations into one and fuzzy it.  */
bool use_first;

/* If true, merge like msgcomm.
   If false, merge like msgcat and msguniq.  */
bool msgcomm_mode = false;

/* If true, omit the header entry.
   If false, keep the header entry present in the input.  */
bool omit_header = false;


static bool
is_message_selected (const message_ty *tmp)
{
  int used = (tmp->used >= 0 ? tmp->used : - tmp->used);

  return (is_header (tmp)
          ? !omit_header        /* keep the header entry */
          : (used > more_than && used < less_than));
}


static bool
is_message_needed (const message_ty *mp)
{
  if (!msgcomm_mode
      && ((!is_header (mp) && mp->is_fuzzy) || mp->msgstr[0] == '\0'))
    /* Weak translation.  Needed if there are only weak translations.  */
    return mp->tmp->used < 0 && is_message_selected (mp->tmp);
  else
    /* Good translation.  */
    return is_message_selected (mp->tmp);
}


/* The use_first logic.  */
static bool
is_message_first_needed (const message_ty *mp)
{
  if (mp->tmp->obsolete && is_message_needed (mp))
    {
      mp->tmp->obsolete = false;
      return true;
    }
  else
    return false;
}


msgdomain_list_ty *
catenate_msgdomain_list (string_list_ty *file_list,
                         catalog_input_format_ty input_syntax,
                         const char *to_code)
{
  const char * const *files = file_list->item;
  size_t nfiles = file_list->nitems;
  msgdomain_list_ty **mdlps;
  const char ***canon_charsets;
  const char ***identifications;
  msgdomain_list_ty *total_mdlp;
  const char *canon_to_code;
  size_t n, j;

  /* Read input files.  */
  mdlps = XNMALLOC (nfiles, msgdomain_list_ty *);
  for (n = 0; n < nfiles; n++)
    mdlps[n] = read_catalog_file (files[n], input_syntax);

  /* Determine the canonical name of each input file's encoding.  */
  canon_charsets = XNMALLOC (nfiles, const char **);
  for (n = 0; n < nfiles; n++)
    {
      msgdomain_list_ty *mdlp = mdlps[n];
      size_t k;

      canon_charsets[n] = XNMALLOC (mdlp->nitems, const char *);
      for (k = 0; k < mdlp->nitems; k++)
        {
          message_list_ty *mlp = mdlp->item[k]->messages;
          const char *canon_from_code = NULL;

          if (mlp->nitems > 0)
            {
              for (j = 0; j < mlp->nitems; j++)
                if (is_header (mlp->item[j]) && !mlp->item[j]->obsolete)
                  {
                    const char *header = mlp->item[j]->msgstr;

                    if (header != NULL)
                      {
                        const char *charsetstr = c_strstr (header, "charset=");

                        if (charsetstr != NULL)
                          {
                            size_t len;
                            char *charset;
                            const char *canon_charset;

                            charsetstr += strlen ("charset=");
                            len = strcspn (charsetstr, " \t\n");
                            charset = (char *) xmalloca (len + 1);
                            memcpy (charset, charsetstr, len);
                            charset[len] = '\0';

                            canon_charset = po_charset_canonicalize (charset);
                            if (canon_charset == NULL)
                              {
                                /* Don't give an error for POT files, because
                                   POT files usually contain only ASCII
                                   msgids.  */
                                const char *filename = files[n];
                                size_t filenamelen = strlen (filename);

                                if (filenamelen >= 4
                                    && memcmp (filename + filenamelen - 4,
                                               ".pot", 4) == 0
                                    && strcmp (charset, "CHARSET") == 0)
                                  canon_charset = po_charset_ascii;
                                else
                                  error (EXIT_FAILURE, 0,
                                         _("present charset \"%s\" is not a portable encoding name"),
                                         charset);
                              }

                            freea (charset);

                            if (canon_from_code == NULL)
                              canon_from_code = canon_charset;
                            else if (canon_from_code != canon_charset)
                              error (EXIT_FAILURE, 0,
                                     _("two different charsets \"%s\" and \"%s\" in input file"),
                                     canon_from_code, canon_charset);
                          }
                      }
                  }
              if (canon_from_code == NULL)
                {
                  if (is_ascii_message_list (mlp))
                    canon_from_code = po_charset_ascii;
                  else if (mdlp->encoding != NULL)
                    canon_from_code = mdlp->encoding;
                  else
                    {
                      if (k == 0)
                        error (EXIT_FAILURE, 0,
                               _("input file '%s' doesn't contain a header entry with a charset specification"),
                               files[n]);
                      else
                        error (EXIT_FAILURE, 0,
                               _("domain \"%s\" in input file '%s' doesn't contain a header entry with a charset specification"),
                               mdlp->item[k]->domain, files[n]);
                    }
                }
            }
          canon_charsets[n][k] = canon_from_code;
        }
    }

  /* Determine textual identifications of each file/domain combination.  */
  identifications = XNMALLOC (nfiles, const char **);
  for (n = 0; n < nfiles; n++)
    {
      const char *filename = last_component (files[n]);
      msgdomain_list_ty *mdlp = mdlps[n];
      size_t k;

      identifications[n] = XNMALLOC (mdlp->nitems, const char *);
      for (k = 0; k < mdlp->nitems; k++)
        {
          const char *domain = mdlp->item[k]->domain;
          message_list_ty *mlp = mdlp->item[k]->messages;
          char *project_id = NULL;

          for (j = 0; j < mlp->nitems; j++)
            if (is_header (mlp->item[j]) && !mlp->item[j]->obsolete)
              {
                const char *header = mlp->item[j]->msgstr;

                if (header != NULL)
                  {
                    const char *cp = c_strstr (header, "Project-Id-Version:");

                    if (cp != NULL)
                      {
                        const char *endp;

                        cp += sizeof ("Project-Id-Version:") - 1;

                        endp = strchr (cp, '\n');
                        if (endp == NULL)
                          endp = cp + strlen (cp);

                        while (cp < endp && *cp == ' ')
                          cp++;

                        if (cp < endp)
                          {
                            size_t len = endp - cp;
                            project_id = XNMALLOC (len + 1, char);
                            memcpy (project_id, cp, len);
                            project_id[len] = '\0';
                          }
                        break;
                      }
                  }
              }

          identifications[n][k] =
            (project_id != NULL
             ? (k > 0 ? xasprintf ("%s:%s (%s)", filename, domain, project_id)
                      : xasprintf ("%s (%s)", filename, project_id))
             : (k > 0 ? xasprintf ("%s:%s", filename, domain)
                      : xasprintf ("%s", filename)));
        }
    }

  /* Create list of resulting messages, but don't fill it.  Only count
     the number of translations for each message.
     If for a message, there is at least one non-fuzzy, non-empty translation,
     use only the non-fuzzy, non-empty translations.  Otherwise use the
     fuzzy or empty translations as well.  */
  total_mdlp = msgdomain_list_alloc (true);
  for (n = 0; n < nfiles; n++)
    {
      msgdomain_list_ty *mdlp = mdlps[n];
      size_t k;

      for (k = 0; k < mdlp->nitems; k++)
        {
          const char *domain = mdlp->item[k]->domain;
          message_list_ty *mlp = mdlp->item[k]->messages;
          message_list_ty *total_mlp;

          total_mlp = msgdomain_list_sublist (total_mdlp, domain, true);

          for (j = 0; j < mlp->nitems; j++)
            {
              message_ty *mp = mlp->item[j];
              message_ty *tmp;
              size_t i;

              tmp = message_list_search (total_mlp, mp->msgctxt, mp->msgid);
              if (tmp != NULL)
                {
                  if ((tmp->msgid_plural != NULL) != (mp->msgid_plural != NULL))
                    {
                      char *errormsg =
                        xasprintf (_("msgid '%s' is used without plural and with plural."),
                                   mp->msgid);
                      multiline_error (xstrdup (""),
                                       xasprintf ("%s\n", errormsg));
                    }
                }
              else
                {
                  tmp = message_alloc (mp->msgctxt, mp->msgid, mp->msgid_plural,
                                       NULL, 0, &mp->pos);
                  tmp->is_fuzzy = true; /* may be set to false later */
                  for (i = 0; i < NFORMATS; i++)
                    tmp->is_format[i] = undecided; /* may be set to yes/no later */
                  tmp->range.min = - INT_MAX;
                  tmp->range.max = - INT_MAX;
                  tmp->do_wrap = yes; /* may be set to no later */
                  for (i = 0; i < NSYNTAXCHECKS; i++)
                    tmp->do_syntax_check[i] = undecided; /* may be set to yes/no later */
                  tmp->obsolete = true; /* may be set to false later */
                  tmp->alternative_count = 0;
                  tmp->alternative = NULL;
                  message_list_append (total_mlp, tmp);
                }

              if (!msgcomm_mode
                  && ((!is_header (mp) && mp->is_fuzzy)
                      || mp->msgstr[0] == '\0'))
                /* Weak translation.  Counted as negative tmp->used.  */
                {
                  if (tmp->used <= 0)
                    tmp->used--;
                }
              else
                /* Good translation.  Counted as positive tmp->used.  */
                {
                  if (tmp->used < 0)
                    tmp->used = 0;
                  tmp->used++;
                }
              mp->tmp = tmp;
            }
        }
    }

  /* Remove messages that are not used and need not be converted.  */
  for (n = 0; n < nfiles; n++)
    {
      msgdomain_list_ty *mdlp = mdlps[n];
      size_t k;

      for (k = 0; k < mdlp->nitems; k++)
        {
          message_list_ty *mlp = mdlp->item[k]->messages;

          message_list_remove_if_not (mlp,
                                      use_first
                                      ? is_message_first_needed
                                      : is_message_needed);

          /* If no messages are remaining, drop the charset.  */
          if (mlp->nitems == 0)
            canon_charsets[n][k] = NULL;
        }
    }
  {
    size_t k;

    for (k = 0; k < total_mdlp->nitems; k++)
      {
        message_list_ty *mlp = total_mdlp->item[k]->messages;

        message_list_remove_if_not (mlp, is_message_selected);
      }
  }

  /* Determine the common known a-priori encoding, if any.  */
  if (nfiles > 0)
    {
      bool all_same_encoding = true;

      for (n = 1; n < nfiles; n++)
        if (mdlps[n]->encoding != mdlps[0]->encoding)
          {
            all_same_encoding = false;
            break;
          }

      if (all_same_encoding)
        total_mdlp->encoding = mdlps[0]->encoding;
    }

  /* Determine whether we need a target encoding that contains the control
     characters needed for escaping file names with spaces.  */
  bool has_filenames_with_spaces = false;
  for (n = 0; n < nfiles; n++)
    {
      has_filenames_with_spaces =
        has_filenames_with_spaces
        || msgdomain_list_has_filenames_with_spaces (mdlps[n]);
    }

  /* Determine the target encoding for the remaining messages.  */
  if (to_code != NULL)
    {
      /* Canonicalize target encoding.  */
      canon_to_code = po_charset_canonicalize (to_code);
      if (canon_to_code == NULL)
        error (EXIT_FAILURE, 0,
               _("target charset \"%s\" is not a portable encoding name."),
               to_code);
      /* Test whether the control characters required for escaping file names
         with spaces are present in the target encoding.  */
      if (has_filenames_with_spaces
          && !(canon_to_code == po_charset_utf8
               || strcmp (canon_to_code, "GB18030") == 0))
        error (EXIT_FAILURE, 0,
               _("Cannot write the control characters that protect file names with spaces in the %s encoding"),
               canon_to_code);
    }
  else
    {
      /* No target encoding was specified.  Test whether the messages are
         all in a single encoding.  If so and if !has_filenames_with_spaces,
         conversion is not needed.  */
      const char *first = NULL;
      const char *second = NULL;
      bool with_ASCII = false;
      bool with_UTF8 = false;
      bool all_ASCII_compatible = true;

      for (n = 0; n < nfiles; n++)
        {
          msgdomain_list_ty *mdlp = mdlps[n];
          size_t k;

          for (k = 0; k < mdlp->nitems; k++)
            if (canon_charsets[n][k] != NULL)
              {
                if (canon_charsets[n][k] == po_charset_ascii)
                  with_ASCII = true;
                else
                  {
                    if (first == NULL)
                      first = canon_charsets[n][k];
                    else if (canon_charsets[n][k] != first && second == NULL)
                      second = canon_charsets[n][k];

                    if (strcmp (canon_charsets[n][k], "UTF-8") == 0)
                      with_UTF8 = true;

                    if (!po_charset_ascii_compatible (canon_charsets[n][k]))
                      all_ASCII_compatible = false;
                  }
              }
        }

      if (with_ASCII && !all_ASCII_compatible)
        {
          /* assert (first != NULL); */
          if (second == NULL)
            second = po_charset_ascii;
        }

      if (second != NULL)
        {
          /* A conversion is needed.  Warn the user since he hasn't asked
             for it and might be surprised.  */
          if (with_UTF8)
            multiline_warning (xasprintf (_("warning: ")),
                               xasprintf (_("\
Input files contain messages in different encodings, UTF-8 among others.\n\
Converting the output to UTF-8.\n\
")));
          else
            multiline_warning (xasprintf (_("warning: ")),
                               xasprintf (_("\
Input files contain messages in different encodings, %s and %s among others.\n\
Converting the output to UTF-8.\n\
To select a different output encoding, use the --to-code option.\n\
"), first, second));
          canon_to_code = po_charset_utf8;
        }
      else if (has_filenames_with_spaces)
        {
          /* A conversion is needed.  Warn the user since he hasn't asked
             for it and might be surprised.  */
          if (first != NULL
              && (first == po_charset_utf8 || strcmp (first, "GB18030") == 0))
            canon_to_code = first;
          else
            canon_to_code = po_charset_utf8;
          multiline_warning (xasprintf (_("warning: ")),
                             xasprintf (_("\
Input files contain messages referenced in file names with spaces.\n\
Converting the output to %s.\n\
"),
                                        canon_to_code));
        }
      else if (first != NULL && with_ASCII && all_ASCII_compatible)
        {
          /* The conversion is a no-op conversion.  Don't warn the user,
             but still perform the conversion, in order to check that the
             input was really ASCII.  */
          canon_to_code = first;
        }
      else
        {
          /* No conversion needed.  */
          canon_to_code = NULL;
        }
    }

  /* Now convert the remaining messages to canon_to_code.  */
  if (canon_to_code != NULL)
    for (n = 0; n < nfiles; n++)
      {
        msgdomain_list_ty *mdlp = mdlps[n];
        size_t k;

        for (k = 0; k < mdlp->nitems; k++)
          if (canon_charsets[n][k] != NULL)
            /* If the user hasn't given a to_code, don't bother doing a noop
               conversion that would only replace the charset name in the
               header entry with its canonical equivalent.  */
            if (!(to_code == NULL && canon_charsets[n][k] == canon_to_code))
              if (iconv_message_list (mdlp->item[k]->messages,
                                      canon_charsets[n][k], canon_to_code,
                                      files[n]))
                {
                  multiline_error (xstrdup (""),
                                   xasprintf (_("\
Conversion of file %s from %s encoding to %s encoding\n\
changes some msgids or msgctxts.\n\
Either change all msgids and msgctxts to be pure ASCII, or ensure they are\n\
UTF-8 encoded from the beginning, i.e. already in your source code files.\n"),
                                              files[n], canon_charsets[n][k],
                                              canon_to_code));
                  exit (EXIT_FAILURE);
                }
      }

  /* Fill the resulting messages.  */
  for (n = 0; n < nfiles; n++)
    {
      msgdomain_list_ty *mdlp = mdlps[n];
      size_t k;

      for (k = 0; k < mdlp->nitems; k++)
        {
          message_list_ty *mlp = mdlp->item[k]->messages;

          for (j = 0; j < mlp->nitems; j++)
            {
              message_ty *mp = mlp->item[j];
              message_ty *tmp = mp->tmp;
              size_t i;

              /* No need to discard unneeded weak translations here;
                 they have already been filtered out above.  */
              if (use_first || tmp->used == 1 || tmp->used == -1)
                {
                  /* Copy mp, as only message, into tmp.  */
                  tmp->msgstr = mp->msgstr;
                  tmp->msgstr_len = mp->msgstr_len;
                  tmp->pos = mp->pos;
                  if (mp->comment)
                    for (i = 0; i < mp->comment->nitems; i++)
                      message_comment_append (tmp, mp->comment->item[i]);
                  if (mp->comment_dot)
                    for (i = 0; i < mp->comment_dot->nitems; i++)
                      message_comment_dot_append (tmp,
                                                  mp->comment_dot->item[i]);
                  for (i = 0; i < mp->filepos_count; i++)
                    message_comment_filepos (tmp, mp->filepos[i].file_name,
                                             mp->filepos[i].line_number);
                  tmp->is_fuzzy = mp->is_fuzzy;
                  for (i = 0; i < NFORMATS; i++)
                    tmp->is_format[i] = mp->is_format[i];
                  tmp->range = mp->range;
                  tmp->do_wrap = mp->do_wrap;
                  for (i = 0; i < NSYNTAXCHECKS; i++)
                    tmp->do_syntax_check[i] = mp->do_syntax_check[i];
                  tmp->prev_msgctxt = mp->prev_msgctxt;
                  tmp->prev_msgid = mp->prev_msgid;
                  tmp->prev_msgid_plural = mp->prev_msgid_plural;
                  tmp->obsolete = mp->obsolete;
                }
              else if (msgcomm_mode)
                {
                  /* Copy mp, as only message, into tmp.  */
                  if (tmp->msgstr == NULL)
                    {
                      tmp->msgstr = mp->msgstr;
                      tmp->msgstr_len = mp->msgstr_len;
                      tmp->pos = mp->pos;
                      tmp->is_fuzzy = mp->is_fuzzy;
                      tmp->prev_msgctxt = mp->prev_msgctxt;
                      tmp->prev_msgid = mp->prev_msgid;
                      tmp->prev_msgid_plural = mp->prev_msgid_plural;
                    }
                  if (mp->comment && tmp->comment == NULL)
                    for (i = 0; i < mp->comment->nitems; i++)
                      message_comment_append (tmp, mp->comment->item[i]);
                  if (mp->comment_dot && tmp->comment_dot == NULL)
                    for (i = 0; i < mp->comment_dot->nitems; i++)
                      message_comment_dot_append (tmp,
                                                  mp->comment_dot->item[i]);
                  for (i = 0; i < mp->filepos_count; i++)
                    message_comment_filepos (tmp, mp->filepos[i].file_name,
                                             mp->filepos[i].line_number);
                  for (i = 0; i < NFORMATS; i++)
                    if (tmp->is_format[i] == undecided)
                      tmp->is_format[i] = mp->is_format[i];
                  if (tmp->range.min == - INT_MAX
                      && tmp->range.max == - INT_MAX)
                    tmp->range = mp->range;
                  else if (has_range_p (mp->range) && has_range_p (tmp->range))
                    {
                      if (mp->range.min < tmp->range.min)
                        tmp->range.min = mp->range.min;
                      if (mp->range.max > tmp->range.max)
                        tmp->range.max = mp->range.max;
                    }
                  else
                    {
                      tmp->range.min = -1;
                      tmp->range.max = -1;
                    }
                  if (tmp->do_wrap == undecided)
                    tmp->do_wrap = mp->do_wrap;
                  for (i = 0; i < NSYNTAXCHECKS; i++)
                    if (tmp->do_syntax_check[i] == undecided)
                      tmp->do_syntax_check[i] = mp->do_syntax_check[i];
                  tmp->obsolete = false;
                }
              else
                {
                  /* Copy mp, among others, into tmp.  */
                  char *id = xasprintf ("#-#-#-#-#  %s  #-#-#-#-#",
                                        identifications[n][k]);
                  size_t nbytes;

                  if (tmp->alternative_count == 0)
                    tmp->pos = mp->pos;

                  i = tmp->alternative_count;
                  nbytes = (i + 1) * sizeof (struct altstr);
                  tmp->alternative = xrealloc (tmp->alternative, nbytes);
                  tmp->alternative[i].msgstr = mp->msgstr;
                  tmp->alternative[i].msgstr_len = mp->msgstr_len;
                  tmp->alternative[i].msgstr_end =
                    tmp->alternative[i].msgstr + tmp->alternative[i].msgstr_len;
                  tmp->alternative[i].comment = mp->comment;
                  tmp->alternative[i].comment_dot = mp->comment_dot;
                  tmp->alternative[i].id = id;
                  tmp->alternative_count = i + 1;

                  for (i = 0; i < mp->filepos_count; i++)
                    message_comment_filepos (tmp, mp->filepos[i].file_name,
                                             mp->filepos[i].line_number);
                  if (!mp->is_fuzzy)
                    tmp->is_fuzzy = false;
                  for (i = 0; i < NFORMATS; i++)
                    if (mp->is_format[i] == yes)
                      tmp->is_format[i] = yes;
                    else if (mp->is_format[i] == no
                             && tmp->is_format[i] == undecided)
                      tmp->is_format[i] = no;
                  if (tmp->range.min == - INT_MAX
                      && tmp->range.max == - INT_MAX)
                    tmp->range = mp->range;
                  else if (has_range_p (mp->range) && has_range_p (tmp->range))
                    {
                      if (mp->range.min < tmp->range.min)
                        tmp->range.min = mp->range.min;
                      if (mp->range.max > tmp->range.max)
                        tmp->range.max = mp->range.max;
                    }
                  else
                    {
                      tmp->range.min = -1;
                      tmp->range.max = -1;
                    }
                  if (mp->do_wrap == no)
                    tmp->do_wrap = no;
                  for (i = 0; i < NSYNTAXCHECKS; i++)
                    if (mp->do_syntax_check[i] == yes)
                      tmp->do_syntax_check[i] = yes;
                    else if (mp->do_syntax_check[i] == no
                             && tmp->do_syntax_check[i] == undecided)
                      tmp->do_syntax_check[i] = no;
                  /* Don't fill tmp->prev_msgid in this case.  */
                  if (!mp->obsolete)
                    tmp->obsolete = false;
                }
            }
        }
    }
  {
    size_t k;

    for (k = 0; k < total_mdlp->nitems; k++)
      {
        message_list_ty *mlp = total_mdlp->item[k]->messages;

        for (j = 0; j < mlp->nitems; j++)
          {
            message_ty *tmp = mlp->item[j];

            if (tmp->alternative_count > 0)
              {
                /* Test whether all alternative translations are equal.  */
                struct altstr *first = &tmp->alternative[0];
                size_t i;

                for (i = 0; i < tmp->alternative_count; i++)
                  if (!(tmp->alternative[i].msgstr_len == first->msgstr_len
                        && memcmp (tmp->alternative[i].msgstr, first->msgstr,
                                   first->msgstr_len) == 0))
                    break;

                if (i == tmp->alternative_count)
                  {
                    /* All alternatives are equal.  */
                    tmp->msgstr = first->msgstr;
                    tmp->msgstr_len = first->msgstr_len;
                  }
                else
                  {
                    /* Concatenate the alternative msgstrs into a single one,
                       separated by markers.  */
                    size_t len;
                    const char *p;
                    const char *p_end;
                    char *new_msgstr;
                    char *np;

                    len = 0;
                    for (i = 0; i < tmp->alternative_count; i++)
                      {
                        size_t id_len = strlen (tmp->alternative[i].id);

                        len += tmp->alternative[i].msgstr_len;

                        p = tmp->alternative[i].msgstr;
                        p_end = tmp->alternative[i].msgstr_end;
                        for (; p < p_end; p += strlen (p) + 1)
                          len += id_len + 2;
                      }

                    new_msgstr = XNMALLOC (len, char);
                    np = new_msgstr;
                    for (;;)
                      {
                        /* Test whether there's one more plural form to
                           process.  */
                        for (i = 0; i < tmp->alternative_count; i++)
                          if (tmp->alternative[i].msgstr
                              < tmp->alternative[i].msgstr_end)
                            break;
                        if (i == tmp->alternative_count)
                          break;

                        /* Process next plural form.  */
                        for (i = 0; i < tmp->alternative_count; i++)
                          if (tmp->alternative[i].msgstr
                              < tmp->alternative[i].msgstr_end)
                            {
                              if (np > new_msgstr && np[-1] != '\0'
                                  && np[-1] != '\n')
                                *np++ = '\n';

                              len = strlen (tmp->alternative[i].id);
                              memcpy (np, tmp->alternative[i].id, len);
                              np += len;
                              *np++ = '\n';

                              len = strlen (tmp->alternative[i].msgstr);
                              memcpy (np, tmp->alternative[i].msgstr, len);
                              np += len;
                              tmp->alternative[i].msgstr += len + 1;
                            }

                        /* Plural forms are separated by NUL bytes.  */
                        *np++ = '\0';
                      }
                    tmp->msgstr = new_msgstr;
                    tmp->msgstr_len = np - new_msgstr;

                    tmp->is_fuzzy = true;
                  }

                /* Test whether all alternative comments are equal.  */
                for (i = 0; i < tmp->alternative_count; i++)
                  if (tmp->alternative[i].comment == NULL
                      || !string_list_equal (tmp->alternative[i].comment,
                                             first->comment))
                    break;

                if (i == tmp->alternative_count)
                  /* All alternatives are equal.  */
                  tmp->comment = first->comment;
                else
                  /* Concatenate the alternative comments into a single one,
                     separated by markers.  */
                  for (i = 0; i < tmp->alternative_count; i++)
                    {
                      string_list_ty *slp = tmp->alternative[i].comment;

                      if (slp != NULL)
                        {
                          size_t l;

                          message_comment_append (tmp, tmp->alternative[i].id);
                          for (l = 0; l < slp->nitems; l++)
                            message_comment_append (tmp, slp->item[l]);
                        }
                    }

                /* Test whether all alternative dot comments are equal.  */
                for (i = 0; i < tmp->alternative_count; i++)
                  if (tmp->alternative[i].comment_dot == NULL
                      || !string_list_equal (tmp->alternative[i].comment_dot,
                                             first->comment_dot))
                    break;

                if (i == tmp->alternative_count)
                  /* All alternatives are equal.  */
                  tmp->comment_dot = first->comment_dot;
                else
                  /* Concatenate the alternative dot comments into a single one,
                     separated by markers.  */
                  for (i = 0; i < tmp->alternative_count; i++)
                    {
                      string_list_ty *slp = tmp->alternative[i].comment_dot;

                      if (slp != NULL)
                        {
                          size_t l;

                          message_comment_dot_append (tmp,
                                                      tmp->alternative[i].id);
                          for (l = 0; l < slp->nitems; l++)
                            message_comment_dot_append (tmp, slp->item[l]);
                        }
                    }
              }
          }
      }
  }

  return total_mdlp;
}
