/* Error handling during reading and writing of PO files.
   Copyright (C) 2005-2007, 2013, 2019 Free Software Foundation, Inc.
   Written by Bruno Haible <bruno@clisp.org>, 2005.

   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

/* Specification.  */
#include "po-xerror.h"

#include <error.h>
#include <stdio.h>
#include <stdlib.h>

#include "message.h"
#include "error-progname.h"
#include "xalloc.h"
#include "xerror.h"
#include "error.h"
#include "xvasprintf.h"
#include "po-error.h"
#if IN_LIBGETTEXTPO
# include "getprogname.h"
# define program_name getprogname ()
#else
# include "progname.h"
#endif
#include "gettext.h"

#define _(str) gettext (str)


static void
xerror (int severity, const char *prefix_tail,
        const char *filename, size_t lineno, size_t column,
        int multiline_p, const char *message_text)
{
  if (multiline_p)
    {
      bool old_error_with_progname = error_with_progname;
      char *prefix;

      if (filename != NULL)
        {
          if (lineno != (size_t)(-1))
            {
              if (column != (size_t)(-1))
                prefix =
                  xasprintf ("%s:%ld:%ld: %s", filename,
                             (long) lineno, (long) column, prefix_tail);
              else
                prefix =
                  xasprintf ("%s:%ld: %s", filename,
                             (long) lineno, prefix_tail);
            }
          else
            prefix = xasprintf ("%s: %s", filename, prefix_tail);
          error_with_progname = false;
        }
      else
        prefix = xasprintf ("%s: %s", program_name, prefix_tail);

      if (severity >= PO_SEVERITY_ERROR)
        po_multiline_error (prefix, xstrdup (message_text));
      else
        po_multiline_warning (prefix, xstrdup (message_text));
      error_with_progname = old_error_with_progname;

      if (severity == PO_SEVERITY_FATAL_ERROR)
        exit (EXIT_FAILURE);
    }
  else
    {
      int exit_status =
        (severity == PO_SEVERITY_FATAL_ERROR ? EXIT_FAILURE : 0);

      if (filename != NULL)
        {
          error_with_progname = false;
          if (lineno != (size_t)(-1))
            {
              if (column != (size_t)(-1))
                po_error (exit_status, 0, "%s:%ld:%ld: %s%s",
                          filename, (long) lineno, (long) column,
                          prefix_tail, message_text);
              else
                po_error_at_line (exit_status, 0, filename, lineno, "%s%s",
                                  prefix_tail, message_text);
            }
          else
            po_error (exit_status, 0, "%s: %s%s",
                      filename, prefix_tail, message_text);
          error_with_progname = true;
        }
      else
        po_error (exit_status, 0, "%s%s", prefix_tail, message_text);
      if (severity < PO_SEVERITY_ERROR)
        --error_message_count;
    }
}

/* The default error handler is based on the lower-level error handler
   in po-error.h, so that gettext-po.h can offer to override one or the
   other.  */
void
textmode_xerror (int severity,
                 const struct message_ty *message,
                 const char *filename, size_t lineno, size_t column,
                 int multiline_p, const char *message_text)
{
  const char *prefix_tail =
    (severity == PO_SEVERITY_WARNING ? _("warning: ") : "");

  if (message != NULL && (filename == NULL || lineno == (size_t)(-1)))
    {
      filename = message->pos.file_name;
      lineno = message->pos.line_number;
      column = (size_t)(-1);
    }

  xerror (severity, prefix_tail, filename, lineno, column,
          multiline_p, message_text);
}

void
textmode_xerror2 (int severity,
                  const struct message_ty *message1,
                  const char *filename1, size_t lineno1, size_t column1,
                  int multiline_p1, const char *message_text1,
                  const struct message_ty *message2,
                  const char *filename2, size_t lineno2, size_t column2,
                  int multiline_p2, const char *message_text2)
{
  int severity1 = /* Don't exit before both texts have been output.  */
    (severity == PO_SEVERITY_FATAL_ERROR ? PO_SEVERITY_ERROR : severity);
  const char *prefix_tail =
    (severity == PO_SEVERITY_WARNING ? _("warning: ") : "");

  if (message1 != NULL && (filename1 == NULL || lineno1 == (size_t)(-1)))
    {
      filename1 = message1->pos.file_name;
      lineno1 = message1->pos.line_number;
      column1 = (size_t)(-1);
    }

  if (message2 != NULL && (filename2 == NULL || lineno2 == (size_t)(-1)))
    {
      filename2 = message2->pos.file_name;
      lineno2 = message2->pos.line_number;
      column2 = (size_t)(-1);
    }

  if (multiline_p1)
    xerror (severity1, prefix_tail, filename1, lineno1, column1, multiline_p1,
            message_text1);
  else
    {
      char *message_text1_extended = xasprintf ("%s...", message_text1);
      xerror (severity1, prefix_tail, filename1, lineno1, column1,
              multiline_p1, message_text1_extended);
      free (message_text1_extended);
    }

  {
    char *message_text2_extended = xasprintf ("...%s", message_text2);
    xerror (severity, prefix_tail, filename2, lineno2, column2,
            multiline_p2, message_text2_extended);
    free (message_text2_extended);
  }

  if (severity >= PO_SEVERITY_ERROR)
    /* error_message_count needs to be incremented only by 1, not by 2.  */
    --error_message_count;
}

void (*po_xerror) (int severity,
                   const struct message_ty *message,
                   const char *filename, size_t lineno, size_t column,
                   int multiline_p, const char *message_text)
  = textmode_xerror;

void (*po_xerror2) (int severity,
                    const struct message_ty *message1,
                    const char *filename1, size_t lineno1, size_t column1,
                    int multiline_p1, const char *message_text1,
                    const struct message_ty *message2,
                    const char *filename2, size_t lineno2, size_t column2,
                    int multiline_p2, const char *message_text2)
  = textmode_xerror2;
