/*
 * Copyright (c) 1994 Cygnus Support.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms are permitted
 * provided that the above copyright notice and this paragraph are
 * duplicated in all such forms and that any documentation,
 * and/or other materials related to such
 * distribution and use acknowledge that the software was developed
 * at Cygnus Support, Inc.  Cygnus Support, Inc. may not be used to
 * endorse or promote products derived from this software without
 * specific prior written permission.
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */
#define _GNU_SOURCE
#define HAVE_FLOAT 1
#define X(x)       (char *)x

#include <math.h>
#include <float.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>

#ifdef INCLUDE_GENERATE
#define TEST_CONST
#else
#ifdef _RX_PID
#define TEST_CONST
#else
#define TEST_CONST const
#endif
#endif

/* FIXME FIXME FIXME:
   Neither of __ieee_{float,double}_shape_type seem to be used anywhere
   except in libm/test.  If that is the case, please delete these from here.
   If that is not the case, please insert documentation here describing why
   they're needed.  */

#ifdef __IEEE_BIG_ENDIAN

typedef union {
    double value;
    struct {
        unsigned int sign      : 1;
        unsigned int exponent  : 11;
        unsigned int fraction0 : 4;
        unsigned int fraction1 : 16;
        unsigned int fraction2 : 16;
        unsigned int fraction3 : 16;

    } number;
    struct {
        unsigned int sign      : 1;
        unsigned int exponent  : 11;
        unsigned int quiet     : 1;
        unsigned int function0 : 3;
        unsigned int function1 : 16;
        unsigned int function2 : 16;
        unsigned int function3 : 16;
    } nan;
    struct {
        uint32_t msw;
        uint32_t lsw;
    } parts;
    int32_t aslong[2];
} __ieee_double_shape_type;

#else

typedef union {
    double value;
    struct {
#ifdef __SMALL_BITFIELDS
        uint32_t fraction3 : 16;
        uint32_t fraction2 : 16;
        uint32_t fraction1 : 16;
        uint32_t fraction0 : 4;
#else
        uint32_t fraction1 : 32;
        uint32_t fraction0 : 20;
#endif
        uint32_t exponent : 11;
        uint32_t sign     : 1;
    } number;
    struct {
#ifdef __SMALL_BITFIELDS
        uint32_t function3 : 16;
        uint32_t function2 : 16;
        uint32_t function1 : 16;
        uint32_t function0 : 3;
#else
        uint32_t function1 : 32;
        uint32_t function0 : 19;
#endif
        uint32_t quiet    : 1;
        uint32_t exponent : 11;
        uint32_t sign     : 1;
    } nan;
    struct {
        uint32_t lsw;
        uint32_t msw;
    } parts;

    int32_t aslong[2];

} __ieee_double_shape_type;

#endif /* __IEEE_LITTLE_ENDIAN */

#ifdef __IEEE_BIG_ENDIAN

typedef union {
    float value;
    struct {
        uint32_t sign      : 1;
        uint32_t exponent  : 8;
        uint32_t fraction0 : 7;
        uint32_t fraction1 : 16;
    } number;
    struct {
        uint32_t sign      : 1;
        uint32_t exponent  : 8;
        uint32_t quiet     : 1;
        uint32_t function0 : 6;
        uint32_t function1 : 16;
    } nan;
    uint32_t p1;

} __ieee_float_shape_type;

#else

typedef union {
    float value;
    struct {
        uint32_t fraction0 : 7;
        uint32_t fraction1 : 16;
        uint32_t exponent  : 8;
        uint32_t sign      : 1;
    } number;
    struct {
        uint32_t function1 : 16;
        uint32_t function0 : 6;
        uint32_t quiet     : 1;
        uint32_t exponent  : 8;
        uint32_t sign      : 1;
    } nan;
    int32_t p1;

} __ieee_float_shape_type;

#endif /* __IEEE_LITTLE_ENDIAN */

extern int inacc;
extern int redo;
extern int reduce;
extern int verbose;

void       checkf();
void       enter();

double     translate_from();

typedef struct {
    uint32_t msw, lsw;
} question_struct_type;

typedef TEST_CONST struct {
    char                 error_bit;
    char                 errno_val;
    char                 merror;
    int                  line;

    question_struct_type qs[3];
} one_line_type;

#define MVEC_START(x) one_line_type x[] = {
#define MVEC_END \
    0,           \
    }            \
    ;

int mag_of_error(double, double);
int fmag_of_error(float, float);

#define ERROR_PERFECT 20
#define ERROR_FAIL    -1

#define AAAA          15
#define AAA           10
#define AA            6
#define A             5
#define B             3
#define C             1
#define VECOPEN(x, f)                                   \
    {                                                   \
        char buffer[100];                               \
        sprintf(buffer, "%s_vec.c", x);                 \
        f = fopen(buffer, "w");                         \
        if (!f) {                                       \
            perror(buffer);                             \
            exit(1);                                    \
        }                                               \
        fprintf(f, "#include \"test.h\"\n");            \
        fprintf(f, " one_line_type %s_vec[] = {\n", x); \
    }

#define VECCLOSE(f, name, args)                              \
    do {                                                     \
        fprintf(f, "0,};\n");                                \
        fprintf(f,                                           \
                "test_%s(int m)   {run_vector_1(m,%s_vec,"   \
                "(char *)(%s),\"%s\",\"%s\");   }	\n", \
                name, name, name, name, args);               \
        fclose(f);                                           \
    } while (0)

typedef TEST_CONST struct {
    int    line;

    char  *string;
    double value;
    int    endscan;
} double_type;

#define ENDSCAN_MASK    0x7f
#define ENDSCAN_IS_ZERO 0x80
#define ENDSCAN_IS_INF  0x80

typedef TEST_CONST struct {
    long int value;
    char     end;
    char     errno_val;
} int_scan_type;

typedef TEST_CONST struct {
    int           line;
    int_scan_type octal;
    int_scan_type decimal;
    int_scan_type hex;
    int_scan_type normal;
    int_scan_type alphabetical;
    char         *string;
} int_type;

typedef TEST_CONST struct {
    int    line;
    double value;
    char  *estring;
    int    e1;
    int    e2;
    int    e3;
    char  *fstring;
    int    f1;
    int    f2;
    int    f3;
    char  *gstring;
    int    g1;
    char  *gfstring;
} ddouble_type;

typedef TEST_CONST struct {
    int    line;
    double value;
    char  *result;
    char  *format_string;
    int    mag;
} sprint_double_type;

typedef TEST_CONST struct {
    int     line;
    int32_t value;
    char   *result;
    char   *format_string;
} sprint_int_type;

void test_ieee(void);
void test_math2(void);
void test_math(int vector);
void test_string(void);
void test_is(void);
void test_cvt(void);

void line(int);

void test_mok(double, double, int);
void test_mfok(float, float, int);
void test_iok(int, int);
void test_eok(int, int);
void test_sok(char *, char *);
void test_scok(char *, char *, int);
void test_scok2(char *, char *, char *, int);
void newfunc(const char *);

void run_vector_1(int vector, one_line_type *p, char *func, char *name, char *args);
void test_acos(int vector);

void test_acosf(int vector);

void test_acosh(int vector);

void test_acoshf(int vector);

void test_asin(int vector);

void test_asinf(int vector);

void test_asinh(int vector);

void test_asinhf(int vector);

void test_atan(int vector);

void test_atan2(int vector);

void test_atan2f(int vector);

void test_atanf(int vector);

void test_atanh(int vector);

void test_atanhf(int vector);

void test_ceil(int vector);

void test_ceilf(int vector);

void test_copysign(int vector);

void test_copysignf(int vector);

void test_cos(int vector);

void test_cosf(int vector);

void test_cosh(int vector);

void test_coshf(int vector);

void test_erf(int vector);

void test_erfc(int vector);

void test_erfcf(int vector);

void test_erff(int vector);

void test_exp(int vector);

void test_expf(int vector);

void test_fabs(int vector);

void test_fabsf(int vector);

void test_floor(int vector);

void test_floorf(int vector);

void test_fmod(int vector);

void test_fmodf(int vector);

void test_gamma(int vector);

void test_gammaf(int vector);

void test_hypot(int vector);

void test_hypotf(int vector);

void test_issignaling(int vector);

void test_j0(int vector);

void test_j0f(int vector);

void test_j1(int vector);

void test_j1f(int vector);

void test_jn(int vector);

void test_jnf(int vector);

void test_log(int vector);

void test_log10(int vector);

void test_log10f(int vector);

void test_log1p(int vector);

void test_log1pf(int vector);

void test_log2(int vector);

void test_log2f(int vector);

void test_logf(int vector);

void test_modf(int vector);

void test_modff(int vector);

void test_pow_vec(int vector);

void test_powf_vec(int vector);

void test_scalb(int vector);

void test_scalbf(int vector);

void test_scalbn(int vector);

void test_scalbnf(int vector);

void test_sin(int vector);

void test_sinf(int vector);

void test_sinh(int vector);

void test_sinhf(int vector);

void test_sqrt(int vector);

void test_sqrtf(int vector);

void test_tan(int vector);

void test_tanf(int vector);

void test_tanh(int vector);

void test_tanhf(int vector);

void test_trunc(int vector);

void test_truncf(int vector);

void test_y0(int vector);

void test_y0f(int vector);

void test_y1(int vector);

void test_y1f(int vector);

void test_yn(int vector);

void test_ynf(int vector);
