/* strfmon_l override.
   Copyright (C) 2017-2020 Free Software Foundation, Inc.

   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, 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/>.  */

#include <config.h>

/* Specification.  */
#include <monetary.h>

#include <errno.h>
#include <locale.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>

#undef strfmon_l

/* This override can only support a limited number of arguments.  */
#define MAX_ARGS 16

/* A parsed directive.  */
typedef struct
{
  bool needs_long_double;
  const char *conversion_ptr;
}
directive_t;

/* A parsed format string.  */
typedef struct
{
  size_t count;
  directive_t dir[MAX_ARGS];
}
directives_t;

/* Parses a monetary format string.
   Returns 0 and fills *DIRECTIVESP if valid.
   Returns -1 if invalid.  */
static int
fmon_parse (const char *format, directives_t *directivesp)
{
  size_t count = 0;
  const char *cp = format;

  while (*cp != '\0')
    {
      if (*cp++ == '%')
        {
          /* Parse flags.  */
          while (*cp == '=' || *cp == '^' || *cp == '+' || *cp == '('
                 || *cp == '!' || *cp == '-')
            {
              if (*cp == '=')
                {
                  cp++;
                  if (*cp == '\0')
                    return -1;
                }
              cp++;
            }
          /* Parse field width.  */
          while (*cp >= '0' && *cp <= '9')
            cp++;
          /* Parse left precision.  */
          if (*cp == '#')
            {
              cp++;
              while (*cp >= '0' && *cp <= '9')
                cp++;
            }
          /* Parse right precision.  */
          if (*cp == '.')
            {
              cp++;
              while (*cp >= '0' && *cp <= '9')
                cp++;
            }
          /* Now comes the conversion specifier.  */
          if (*cp != '%')
            {
              if (count == MAX_ARGS)
                /* Too many arguments.  */
                return -1;

              /* glibc supports an 'L' modifier before the conversion specifier.  */
              if (*cp == 'L')
                {
                  cp++;
                  directivesp->dir[count].needs_long_double = true;
                }
              else
                directivesp->dir[count].needs_long_double = false;
              if (!(*cp == 'i' || *cp == 'n'))
                return -1;
              directivesp->dir[count].conversion_ptr = cp;
              count++;
            }
          cp++;
        }
    }

  directivesp->count = count;
  return 0;
}

ssize_t
rpl_strfmon_l (char *s, size_t maxsize, locale_t locale, const char *format, ...)
{
  /* Work around glibc 2.23 bug
     <https://sourceware.org/bugzilla/show_bug.cgi?id=19633>.  */
  va_list argptr;
  locale_t orig_locale;
  directives_t directives;
  ssize_t result;

  orig_locale = uselocale ((locale_t)0);

  if (uselocale (locale) == (locale_t)0)
    /* errno is set.  */
    return -1;

  /* The format string may consume 'double' or 'long double' arguments.
     In order not to have to link with libffcall or libffi, convert all
     arguments to 'long double', and use a modified format string that
     requests 'long double' arguments.  But since 'long double' arguments
     are only supported on glibc, do so only if the original format string
     consumes at least one 'long double' argument.  */
  if (fmon_parse (format, &directives) < 0)
    {
      errno = EINVAL;
      result = -1;
    }
  else
    {
      bool use_long_double;
      unsigned int i;

      use_long_double = false;
      for (i = 0; i < directives.count; i++)
        if (directives.dir[i].needs_long_double)
          {
            use_long_double = true;
            break;
          }

      va_start (argptr, format);

      if (use_long_double)
        {
          char *ld_format;

          /* Allocate room for the modified format string.  */
          ld_format = (char *) malloc (strlen (format) + directives.count + 1);
          if (ld_format == NULL)
            {
              errno = ENOMEM;
              result = -1;
            }
          else
            {
              long double args[MAX_ARGS];

              /* Create the modified format string.  */
              {
                const char *p = format;
                char *dest = ld_format;
                for (i = 0; i < directives.count; i++)
                  {
                    const char *q = directives.dir[i].conversion_ptr;
                    memcpy (dest, p, q - p);
                    dest += q - p;
                    if (!directives.dir[i].needs_long_double)
                      *dest++ = 'L';
                    p = q;
                  }
                strcpy (dest, p);
              }

              /* Set up arguments array.  */
              for (i = 0; i < directives.count; i++)
                args[i] = (directives.dir[i].needs_long_double
                           ? va_arg (argptr, long double)
                           : (long double) va_arg (argptr, double));
              /* Avoid uninitialized memory references.  */
              for (; i < MAX_ARGS; i++)
                args[i] = 0.0L;

              result = strfmon_l (s, maxsize, locale, ld_format,
                                  args[0], args[1], args[2], args[3], args[4],
                                  args[5], args[6], args[7], args[8], args[9],
                                  args[10], args[11], args[12], args[13],
                                  args[14], args[15]);

              free (ld_format);
            }
        }
      else
        {
          double args[MAX_ARGS];

          /* Set up arguments array.  */
          for (i = 0; i < directives.count; i++)
            args[i] = va_arg (argptr, double);
          /* Avoid uninitialized memory references.  */
          for (; i < MAX_ARGS; i++)
            args[i] = 0.0;

          result = strfmon_l (s, maxsize, locale, format,
                              args[0], args[1], args[2], args[3], args[4],
                              args[5], args[6], args[7], args[8], args[9],
                              args[10], args[11], args[12], args[13], args[14],
                              args[15]);
        }

      va_end (argptr);
    }

  if (uselocale (orig_locale) == (locale_t)0)
    /* errno is set.  */
    return -1;

  return result;
}
