/* Test for user-defined types in vfprintf.
   Copyright (C) 2017-2018 Free Software Foundation, Inc.
   This file is part of the GNU C Library.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, see
   <http://www.gnu.org/licenses/>.  */

/* This test contains a printf format specifier, %P, with a custom
   type which is a long/double pair.  If a precision is specified,
   this indicates the number of such pairs which constitute the
   argument.  */

#include <locale.h>
#include <printf.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <support/check.h>
#include <support/support.h>
#include <support/test-driver.h>
#include <wchar.h>

/* Initialized by do_test using register_printf_type.  */
static int user_type;

struct two_argument
{
  long i;
  double d;
};

static void
my_va_arg_function (void *mem, va_list *ap)
{
  if (test_verbose > 0)
    printf ("info: %s (%p) called\n", __func__, mem);

  struct two_argument *pair = mem;
  pair->i = va_arg (*ap, long);
  pair->d = va_arg (*ap, double);
}

static int
my_printf_function (FILE *fp, const struct printf_info *info,
                    const void *const *args)
{
  if (test_verbose > 0)
    printf ("info: %s (%p, %p, {%p}@%p) called for %%%lc (prec %d)\n",
            __func__, fp, info, args[0], args, (wint_t) info->spec,
            info->prec);

  TEST_VERIFY (info->spec == 'P');
  size_t nargs;
  int printed;
  if (info->prec >= 0)
    {
      if (fputc ('{', fp) < 0)
        return -1;
      nargs = info->prec;
      printed = 1;
    }
  else
    {
      nargs = 1;
      printed = 0;
    }

  for (size_t i = 0; i < nargs; ++i)
    {
      if (i != 0)
        {
          if (fputc (',', fp) < 0)
            return -1;
          ++printed;
        }

      /* NB: Triple pointer indirection.  ARGS is an array of void *,
         and those pointers point to a pointer to the memory area
         supplied to my_va_arg_function.  */
      struct two_argument *pair = *(void **) args[i];
      int ret = fprintf (fp, "(%ld, %f)", pair->i, pair->d);
      if (ret < 0)
        return -1;
      printed += ret;
    }
  if (info->prec >= 0)
    {
      if (fputc ('}', fp) < 0)
        return -1;
      ++printed;
    }
  return printed;
}

static int
my_arginfo_function (const struct printf_info *info,
                     size_t n, int *argtypes, int *size)
{
  /* Avoid recursion.  */
  if (info->spec != 'P')
    return -1;
  if (test_verbose > 0)
    printf ("info: %s (%p, %zu, %p, %p) called for %%%lc (prec %d)\n",
            __func__, info, n, argtypes, size, (wint_t) info->spec,
            info->prec);

  TEST_VERIFY_EXIT (n >= 1);
  size_t nargs;
  if (info->prec >= 0)
    nargs = info->prec;
  else
    nargs = 1;

  size_t to_fill = nargs;
  if (to_fill > n)
    to_fill = n;
  for (size_t i = 0; i < to_fill; ++i)
    {
      argtypes[i] = user_type;
      size[i] = sizeof (struct two_argument);
    }
  if (test_verbose > 0)
    printf ("info:   %s return value: %zu\n", __func__, nargs);
  return nargs;
}

static int
do_test (void)
{
  user_type = register_printf_type (my_va_arg_function);
  if (test_verbose > 0)
    printf ("info: allocated user type: %d\n", user_type);
  TEST_VERIFY_EXIT (user_type >= PA_LAST);
  TEST_VERIFY_EXIT (register_printf_specifier
                    ('P', my_printf_function, my_arginfo_function) >= 0);

  /* Alias declaration for asprintf, to avoid the format string
     attribute and the associated warning.  */
  extern int asprintf_alias (char **, const char *, ...) __asm__ ("asprintf");
  TEST_VERIFY (asprintf_alias == asprintf);
  char *str = NULL;
  TEST_VERIFY (asprintf_alias (&str, "[[%P]]", 123L, 456.0) >= 0);
  if (test_verbose > 0)
    printf ("info: %s\n", str);
  TEST_VERIFY (strcmp (str, "[[(123, 456.000000)]]") == 0);
  free (str);

  str = NULL;
  TEST_VERIFY (asprintf_alias (&str, "[[%1$P %1$P]]", 123L, 457.0) >= 0);
  if (test_verbose > 0)
    printf ("info: %s\n", str);
  TEST_VERIFY (strcmp (str, "[[(123, 457.000000) (123, 457.000000)]]") == 0);
  free (str);

  str = NULL;
  TEST_VERIFY (asprintf_alias (&str, "[[%.1P]]", 1L, 2.0) >= 0);
  if (test_verbose > 0)
    printf ("info: %s\n", str);
  TEST_VERIFY (strcmp (str, "[[{(1, 2.000000)}]]") == 0);
  free (str);

  str = NULL;
  TEST_VERIFY (asprintf_alias (&str, "[[%.2P]]", 1L, 2.0, 3L, 4.0) >= 0);
  if (test_verbose > 0)
    printf ("info: %s\n", str);
  TEST_VERIFY (strcmp (str, "[[{(1, 2.000000),(3, 4.000000)}]]") == 0);
  free (str);

  str = NULL;
  TEST_VERIFY (asprintf_alias
               (&str, "[[%.2P | %.3P]]",
                /* argument 1: */ 1L, 2.0, 3L, 4.0,
                /* argument 2: */ 5L, 6.0, 7L, 8.0, 9L, 10.0)
               >= 0);
  if (test_verbose > 0)
    printf ("info: %s\n", str);
  TEST_VERIFY (strcmp (str,
                       "[["
                       "{(1, 2.000000),(3, 4.000000)}"
                       " | "
                       "{(5, 6.000000),(7, 8.000000),(9, 10.000000)}"
                       "]]") == 0);
  free (str);

  /* The following subtest fails due to bug 21534.  */
#if 0
  str = NULL;
  TEST_VERIFY (asprintf_alias
               (&str, "[[%1$.2P | %2$.3P | %1$.2P]]",
                /* argument 1: */ 1L, 2.0, 3L, 4.0,
                /* argument 2: */ 5L, 6.0, 7L, 8.0, 9L, 10.0)
               >= 0);
  if (test_verbose > 0)
    printf ("info: %s\n", str);
  TEST_VERIFY (strcmp (str,
                       "[["
                       "{(1, 2.000000),(3, 4.000000)}"
                       " | "
                       "{(5, 6.000000),(7, 8.000000),(9, 10.000000)}"
                       " | "
                       "{(1, 2.000000),(3, 4.000000)}"
                       "]]") == 0);
  free (str);
#endif

  return 0;
}

#include <support/test-driver.c>
