/* Area:	closure_call
   Purpose:	Check closures called with many args of mixed types
   Limitations:	none.
   PR:		none.
   Originator:	<david.schneider@picle.org> */

/* { dg-do run } */
#include "ffitest.h"
#include <float.h>
#include <math.h>

#define NARGS 16

static void cls_ret_double_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
			      void* userdata __UNUSED__)
{
  int i;
  double r = 0;
  double t;
  for(i = 0; i < NARGS; i++)
    {
    if(i == 4 || i == 9 || i == 11 || i == 13 || i == 15)
      {
      t = *(long int *)args[i];
      CHECK(t == i+1);
      }
    else
      {
      t = *(double *)args[i];
      CHECK(fabs(t - ((i+1) * 0.1)) < FLT_EPSILON);
      }
    r += t;
    }
  *(double *)resp = r;
}
typedef double (*cls_ret_double)(double, double, double, double, long int,
double, double, double, double, long int, double, long int, double, long int,
double, long int);

int main (void)
{
  ffi_cif cif;
  void *code;
  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
  ffi_type * cl_arg_types[NARGS];
  double res;
  int i;
  double expected = 64.9;

  for(i = 0; i < NARGS; i++)
    {
    if(i == 4 || i == 9 || i == 11 || i == 13 || i == 15)
      cl_arg_types[i] = &ffi_type_slong;
    else
      cl_arg_types[i] = &ffi_type_double;
    }

  /* Initialize the cif */
  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, NARGS,
		     &ffi_type_double, cl_arg_types) == FFI_OK);

  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_double_fn, NULL, code) == FFI_OK);

  res = (((cls_ret_double)code))(0.1, 0.2, 0.3, 0.4, 5, 0.6, 0.7, 0.8, 0.9, 10,
                                 1.1, 12, 1.3, 14, 1.5, 16);
  if (abs(res - expected) < FLT_EPSILON)
    exit(0);
  else
    abort();
}
