/* Format strings.
   Copyright (C) 2001-2010, 2012-2013, 2015, 2019-2020 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

/* Specification.  */
#include "format.h"

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

#include "message.h"
#include "gettext.h"

#define _(str) gettext (str)

/* Table of all format string parsers.  */
struct formatstring_parser *formatstring_parsers[NFORMATS] =
{
  /* format_c */                &formatstring_c,
  /* format_objc */             &formatstring_objc,
  /* format_python */           &formatstring_python,
  /* format_python_brace */     &formatstring_python_brace,
  /* format_java */             &formatstring_java,
  /* format_java_printf */      &formatstring_java_printf,
  /* format_csharp */           &formatstring_csharp,
  /* format_javascript */       &formatstring_javascript,
  /* format_scheme */           &formatstring_scheme,
  /* format_lisp */             &formatstring_lisp,
  /* format_elisp */            &formatstring_elisp,
  /* format_librep */           &formatstring_librep,
  /* format_ruby */             &formatstring_ruby,
  /* format_sh */               &formatstring_sh,
  /* format_awk */              &formatstring_awk,
  /* format_lua */              &formatstring_lua,
  /* format_pascal */           &formatstring_pascal,
  /* format_smalltalk */        &formatstring_smalltalk,
  /* format_qt */               &formatstring_qt,
  /* format_qt_plural */        &formatstring_qt_plural,
  /* format_kde */              &formatstring_kde,
  /* format_kde_kuit */         &formatstring_kde_kuit,
  /* format_boost */            &formatstring_boost,
  /* format_tcl */              &formatstring_tcl,
  /* format_perl */             &formatstring_perl,
  /* format_perl_brace */       &formatstring_perl_brace,
  /* format_php */              &formatstring_php,
  /* format_gcc_internal */     &formatstring_gcc_internal,
  /* format_gfc_internal */     &formatstring_gfc_internal,
  /* format_ycp */              &formatstring_ycp
};

/* Check whether both formats strings contain compatible format
   specifications for format type i (0 <= i < NFORMATS).  */
int
check_msgid_msgstr_format_i (const char *msgid, const char *msgid_plural,
                             const char *msgstr, size_t msgstr_len,
                             size_t i,
                             struct argument_range range,
                             const struct plural_distribution *distribution,
                             formatstring_error_logger_t error_logger)
{
  int seen_errors = 0;

  /* At runtime, we can assume the program passes arguments that fit well for
     msgid.  We must signal an error if msgstr wants more arguments that msgid
     accepts.
     If msgstr wants fewer arguments than msgid, it wouldn't lead to a crash
     at runtime, but we nevertheless give an error because
     1) this situation occurs typically after the programmer has added some
        arguments to msgid, so we must make the translator specially aware
        of it (more than just "fuzzy"),
     2) it is generally wrong if a translation wants to ignore arguments that
        are used by other translations.  */

  struct formatstring_parser *parser = formatstring_parsers[i];
  char *invalid_reason = NULL;
  void *msgid_descr =
    parser->parse (msgid_plural != NULL ? msgid_plural : msgid, false, NULL,
                   &invalid_reason);

  if (msgid_descr != NULL)
    {
      const char *pretty_msgid =
        (msgid_plural != NULL ? "msgid_plural" : "msgid");
      char buf[18+1];
      const char *pretty_msgstr = "msgstr";
      bool has_plural_translations = (strlen (msgstr) + 1 < msgstr_len);
      const char *p_end = msgstr + msgstr_len;
      const char *p;
      unsigned int j;

      for (p = msgstr, j = 0; p < p_end; p += strlen (p) + 1, j++)
        {
          void *msgstr_descr;

          if (msgid_plural != NULL)
            {
              sprintf (buf, "msgstr[%u]", j);
              pretty_msgstr = buf;
            }

          msgstr_descr = parser->parse (p, true, NULL, &invalid_reason);

          if (msgstr_descr != NULL)
            {
              /* Use strict checking (require same number of format
                 directives on both sides) if the message has no plurals,
                 or if msgid_plural exists but on the msgstr[] side
                 there is only msgstr[0], or if distribution->often[j]
                 indicates that the variant applies to infinitely many
                 values of N and the N range is not restricted in a way
                 that the variant applies to only one N.
                 Use relaxed checking when there are at least two
                 msgstr[] forms and the distribution does not give more
                 precise information.  */
              bool strict_checking =
                (msgid_plural == NULL
                 || !has_plural_translations
                 || (distribution != NULL
                     && distribution->often != NULL
                     && j < distribution->often_length
                     && distribution->often[j]
                     && !(has_range_p (range)
                          && distribution->histogram (distribution,
                                                      range.min, range.max, j)
                             <= 1)));

              if (parser->check (msgid_descr, msgstr_descr,
                                 strict_checking,
                                 error_logger, pretty_msgid, pretty_msgstr))
                seen_errors++;

              parser->free (msgstr_descr);
            }
          else
            {
              error_logger (_("'%s' is not a valid %s format string, unlike '%s'. Reason: %s"),
                            pretty_msgstr, format_language_pretty[i],
                            pretty_msgid, invalid_reason);
              seen_errors++;
              free (invalid_reason);
            }
        }

      parser->free (msgid_descr);
    }
  else
    free (invalid_reason);

  return seen_errors;
}

/* Check whether both formats strings contain compatible format
   specifications.
   Return the number of errors that were seen.  */
int
check_msgid_msgstr_format (const char *msgid, const char *msgid_plural,
                           const char *msgstr, size_t msgstr_len,
                           const enum is_format is_format[NFORMATS],
                           struct argument_range range,
                           const struct plural_distribution *distribution,
                           formatstring_error_logger_t error_logger)
{
  int seen_errors = 0;
  size_t i;

  /* We check only those messages for which the msgid's is_format flag
     is one of 'yes' or 'possible'.  We don't check msgids with is_format
     'no' or 'impossible', to obey the programmer's order.  We don't check
     msgids with is_format 'undecided' because that would introduce too
     many checks, thus forcing the programmer to add "xgettext: no-c-format"
     anywhere where a translator wishes to use a percent sign.  */
  for (i = 0; i < NFORMATS; i++)
    if (possible_format_p (is_format[i]))
      seen_errors += check_msgid_msgstr_format_i (msgid, msgid_plural,
                                                  msgstr, msgstr_len, i,
                                                  range,
                                                  distribution,
                                                  error_logger);

  return seen_errors;
}
