/* varargs.c - 
 * (Added as part of fix for bug 15306 - "call" to varargs functions fails)
 * This program is intended to let me try out "call" to varargs functions
 * with varying numbers of declared args and various argument types.
 * - RT 9/27/95
 */

#include <stdio.h>
#include <stdarg.h>

#include "../lib/unbuffer_output.c"

int find_max1(int, ...);
int find_max2(int, int, ...);
double find_max_double(int, double, ...);

char ch;
unsigned char uc;
short s;
unsigned short us;
int a,b,c,d;
int max_val;
long long ll;
float fa,fb,fc,fd;
double da,db,dc,dd;
double dmax_val;

#ifdef TEST_COMPLEX
extern float crealf (float _Complex);
extern double creal (double _Complex);
extern long double creall (long double _Complex);

float _Complex fc1 = 1.0F + 1.0iF;
float _Complex fc2 = 2.0F + 2.0iF;
float _Complex fc3 = 3.0F + 3.0iF;
float _Complex fc4 = 4.0F + 4.0iF;

double _Complex dc1 = 1.0 + 1.0i;
double _Complex dc2 = 2.0 + 2.0i;
double _Complex dc3 = 3.0 + 3.0i;
double _Complex dc4 = 4.0 + 4.0i;

long double _Complex ldc1 = 1.0L + 1.0Li;
long double _Complex ldc2 = 2.0L + 2.0Li;
long double _Complex ldc3 = 3.0L + 3.0Li;
long double _Complex ldc4 = 4.0L + 4.0Li;

#endif

int
test (void)
{
  c = -1;
  uc = 1;
  s = -2;
  us = 2;
  a = 1;
  b = 60;
  max_val = find_max1(1, 60);
  max_val = find_max1(a, b);
  a = 3;
  b = 1;
  c = 4;
  d = 2;
  max_val = find_max1(3, 1, 4, 2);
  max_val = find_max2(a, b, c, d);
  da = 3.0;
  db = 1.0;
  dc = 4.0;
  dd = 2.0;
  dmax_val = find_max_double(3, 1.0, 4.0, 2.0);
  dmax_val = find_max_double(a, db, dc, dd);
  
  return 0;
}

int
main (void)
{
  gdb_unbuffer_output ();
  test ();

  return 0;
}

/* Integer varargs, 1 declared arg */

int find_max1(int num_vals, ...) {
  int max_val = 0;
  int x;
  int i;
  va_list argp;
  va_start(argp, num_vals);
  printf("find_max(%d,", num_vals);
  for (i = 0; i < num_vals; i++) {
    x = va_arg(argp, int);
    if (max_val < x) max_val = x;
    if (i < num_vals - 1)
      printf(" %d,", x);
    else
      printf(" %d)", x);
  }
  printf(" returns %d\n", max_val);
  return max_val;
}

/* Integer varargs, 2 declared args */

int find_max2(int num_vals, int first_val, ...) {
  int max_val = 0;
  int x;
  int i;
  va_list argp;
  va_start(argp, first_val);
  x = first_val;
  if (max_val < x) max_val = x;
  printf("find_max(%d, %d", num_vals, first_val);
  for (i = 1; i < num_vals; i++) {
    x = va_arg(argp, int);
    if (max_val < x) max_val = x;
    printf(", %d", x);
  }
  printf(") returns %d\n", max_val);
  return max_val;
}

/* Double-float varargs, 2 declared args */

double find_max_double(int num_vals, double first_val, ...) {
  double max_val = 0;
  double x;
  int i;
  va_list argp;
  va_start(argp, first_val);
  x = first_val;
  if (max_val < x) max_val = x;
  printf("find_max(%d, %f", num_vals, first_val);
  for (i = 1; i < num_vals; i++) {
    x = va_arg(argp, double);
    if (max_val < x) max_val = x;
    printf(", %f", x);
  }
  printf(") returns %f\n", max_val);
  return max_val;
}


#ifdef TEST_COMPLEX
float _Complex
find_max_float_real (int num_vals, ...)
{
  float _Complex max = 0.0F + 0.0iF;
  float _Complex x;
  va_list argp;
  int i;

  va_start(argp, num_vals);
  for (i = 0; i < num_vals; i++)
    {
      x = va_arg (argp, float _Complex);
      if (crealf (max) < crealf (x)) max = x;
    }

  return max;
}

double _Complex
find_max_double_real (int num_vals, ...)
{
  double _Complex max = 0.0 + 0.0i;
  double _Complex x;
  va_list argp;
  int i;

  va_start(argp, num_vals);
  for (i = 0; i < num_vals; i++)
    {
      x = va_arg (argp, double _Complex);
      if (creal (max) < creal (x)) max = x;
    }

  return max;
}

long double _Complex
find_max_long_double_real (int num_vals, ...)
{
  long double _Complex max = 0.0L + 0.0iL;
  long double _Complex x;
  va_list argp;
  int i;

  va_start(argp, num_vals);
  for (i = 0; i < num_vals; i++)
    {
      x = va_arg (argp, long double _Complex);
      if (creall (max) < creal (x)) max = x;
    }

  return max;
}


#endif /* TEST_COMPLEX */
