• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/* -*-c-*- */
2#include "ffitest.h"
3#include <stdio.h>
4#include <stdlib.h>
5#include <stdarg.h>
6#include <complex.h>
7
8static _Complex T_C_TYPE gComplexValue1 = 1 + 2 * I;
9static _Complex T_C_TYPE gComplexValue2 = 3 + 4 * I;
10
11static int cls_variadic(const char *format, ...)
12{
13  va_list ap;
14  _Complex T_C_TYPE p1, p2;
15
16  va_start (ap, format);
17  p1 = va_arg (ap, _Complex T_C_TYPE);
18  p2 = va_arg (ap, _Complex T_C_TYPE);
19  va_end (ap);
20
21  return printf(format, T_CONV creal (p1), T_CONV cimag (p1),
22		T_CONV creal (p2), T_CONV cimag (p2));
23}
24
25static void
26cls_complex_va_fn(ffi_cif* cif __UNUSED__, void* resp,
27		  void** args, void* userdata __UNUSED__)
28{
29  char*	format = *(char**)args[0];
30  gComplexValue1 = *(_Complex T_C_TYPE*)args[1];
31  gComplexValue2 = *(_Complex T_C_TYPE*)args[2];
32
33  *(ffi_arg*)resp =
34    printf(format,
35	   T_CONV creal (gComplexValue1), T_CONV cimag (gComplexValue1),
36	   T_CONV creal (gComplexValue2), T_CONV cimag (gComplexValue2));
37}
38
39int main (void)
40{
41  ffi_cif cif;
42  void *code;
43  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
44  void* args[4];
45  ffi_type* arg_types[4];
46  char *format = "%.1f,%.1fi %.1f,%.1fi\n";
47
48  _Complex T_C_TYPE complexArg1 = 1.0 + 22.0 *I;
49  _Complex T_C_TYPE complexArg2 = 333.0 + 4444.0 *I;
50  ffi_arg res = 0;
51
52  arg_types[0] = &ffi_type_pointer;
53  arg_types[1] = &T_FFI_TYPE;
54  arg_types[2] = &T_FFI_TYPE;
55  arg_types[3] = NULL;
56
57  /* This printf call is variadic */
58  CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 3, &ffi_type_sint,
59			 arg_types) == FFI_OK);
60
61  args[0] = &format;
62  args[1] = &complexArg1;
63  args[2] = &complexArg2;
64  args[3] = NULL;
65
66  ffi_call(&cif, FFI_FN(cls_variadic), &res, args);
67  printf("res: %d\n", (int) res);
68  CHECK (res == 24);
69
70  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_complex_va_fn, NULL, code)
71	== FFI_OK);
72
73  res = ((int(*)(char *, ...))(code))(format, complexArg1, complexArg2);
74  CHECK (gComplexValue1 == complexArg1);
75  CHECK (gComplexValue2 == complexArg2);
76  printf("res: %d\n", (int) res);
77  CHECK (res == 24);
78
79  exit(0);
80}
81