// gcc/config.d is a generated file
module gcc.config;

private import gcc.builtins;
private import gcc.configext;

alias __builtin_Clong Clong_t;
alias __builtin_Culong Culong_t;
// frags-ac.in...


// We don't have long double functions..

extern (C) { // prob doesn't matter..
alias __builtin_acos acosl;
alias __builtin_asin asinl;
alias __builtin_atan atanl;
alias __builtin_atan2 atan2l;
alias __builtin_cos cosl;
alias __builtin_sin sinl;
alias __builtin_tan tanl;
alias __builtin_acosh acoshl;
alias __builtin_asinh asinhl;
alias __builtin_atanh atanhl;
alias __builtin_cosh coshl;
alias __builtin_sinh sinhl;
alias __builtin_tanh tanhl;
alias __builtin_exp expl;
alias __builtin_exp2 exp2l;
alias __builtin_expm1 expm1l;

alias __builtin_frexp frexpl;

alias __builtin_ilogb ilogbl;
alias __builtin_ldexp ldexpl;
alias __builtin_log logl;
alias __builtin_log10 log10l;
alias __builtin_log1p log1pl;
alias __builtin_log2 log2l;
alias __builtin_logb logbl;

//alias gcc.config.modfl __builtin_modf;
extern (D) real modfl(real x, real * py) {
    double dx = x;
    double y;
    double result = __builtin_modf(dx, & y);
    *py = y;
    return result;
}

alias __builtin_scalbn scalbnl;
alias __builtin_scalbln scalblnl;
alias __builtin_cbrt cbrtl;
alias __builtin_fabs fabsl;
alias __builtin_hypot hypotl;
alias __builtin_pow powl;
alias __builtin_sqrt sqrtl;
alias __builtin_erf erfl;
alias __builtin_erfc erfcl;
alias __builtin_lgamma lgammal;
alias __builtin_tgamma tgammal;
alias __builtin_ceil ceill;
alias __builtin_floor floorl;
alias __builtin_nearbyint nearbyintl;
alias __builtin_rint rintl;
alias __builtin_lrint lrintl;
alias __builtin_llrint llrintl;
alias __builtin_round roundl;
alias __builtin_lround lroundl;
alias __builtin_llround llroundl;
alias __builtin_trunc truncl;
alias __builtin_fmod fmodl;
alias __builtin_remainder remainderl;
alias __builtin_remquo remquol;
alias __builtin_copysign copysignl;
//alias __builtin_nan nanl;
real nan(char *);
alias nan nanl;
alias __builtin_nextafter nextafterl;
alias __builtin_nextafter nexttowardl;
alias __builtin_fdim fdiml;
alias __builtin_fmax fmaxl;
alias __builtin_fmin fminl;
alias __builtin_fmal fmal;

alias __builtin_sqrt sqrt;
//alias __builtin_sqrtf sqrtf;//noldfuncs
}


alias __builtin_sqrtf sqrtf;

//   C stdio config for std.stdio
const bool Have_fwide = 1;
const bool Have_getdelim = 0;
const bool Have_fgetln = 1;
const bool Have_fgetline = 0;
const bool Have_Unlocked_Stdio = 1;
const bool Have_Unlocked_Wide_Stdio = 0;

// ...frags-ac.in

// from <dirent.h>
const size_t dirent_d_name_offset = 8;
const size_t dirent_d_name_size = 256;
const size_t dirent_remaining_size = 0;
const size_t DIR_struct_size = 80;

// from <stdlib.h>
const int RAND_MAX = 2147483647;

// from <stdio.h>
const size_t FILE_struct_size = 152;
const int EOF = -1;
const int FOPEN_MAX = 20;
const int FILENAME_MAX = 1024;
const int TMP_MAX = 308915776;
const int L_tmpnam = 1024;
const int PATH_MAX = 1024;

// from <sys/types.h>
alias long Coff_t;
alias ulong Csize_t;
alias long Ctime_t;
alias int Cclock_t;

// from <time.h>
const uint CLOCKS_PER_SEC = 128;
struct tm {
    int tm_sec;
    int tm_min;
    int tm_hour;
    int tm_mday;
    int tm_mon;
    int tm_year;
    int tm_wday;
    int tm_yday;
    int tm_isdst;
   ubyte[4] ___pad1;
    long tm_gmtoff;
    char * tm_zone;
}

static assert(tm.tm_sec.offsetof == 0);
static assert(tm.tm_min.offsetof == 4);
static assert(tm.tm_hour.offsetof == 8);
static assert(tm.tm_mday.offsetof == 12);
static assert(tm.tm_mon.offsetof == 16);
static assert(tm.tm_year.offsetof == 20);
static assert(tm.tm_wday.offsetof == 24);
static assert(tm.tm_yday.offsetof == 28);
static assert(tm.tm_isdst.offsetof == 32);
static assert(tm.tm_gmtoff.offsetof == 40);
static assert(tm.sizeof == 56);


extern(C) {

enum {
  FP_NAN = 2,
  FP_INFINITE = 1,
  FP_ZERO = 16,
  FP_SUBNORMAL = 8,
  FP_NORMAL = 4,
}

}


// TODO: configurate ?  This is a real mess...
version (linux) {
    version(X86)
	version = Use_FP_Math;
    else version(X86_64)
	version = Use_FP_Math;
    else version(PPC)
	version = Use_FP_Math;
    else version(PPC64)
	version = Use_FP_Math;
    else version(SPARC)
	version = Use_FP_Math;
    else version(SPARC64)
	version = Use_FP_Math;
    // any system using IEEE FP is fine, just not listed

} else version (darwin) {
    // could use direct ieee stuff, but long double/real is a problem
  extern (C) {
      // the 'real' versions are declared, but do not actually exist...
      int __isnand(double);
      int __isnanf(float);
      int __isnan(real);
      int __isfinited(double);
      int __isfinitef(float);
      int __isfinite(real);
      int __isnormald(double);
      int __isnormalf(float);
      int __isnormal(real);
      int __fpclassifyd(double);
      int __fpclassifyf(float);
      int __fpclassify(real);
      int __isinfd(double);
      int __isinff(float);
      int __isinf(real);
      int __signbitd(double);
      int __signbitf(float);
      int __signbitl(real);
  }
  
  int isnan(real x) { return __isnand(x); }
  int isfinite(real x) { return __isfinited(x); }
  int isnormal(real x) { return __isnormald(x); }
  int isnormal(double x) { return __isnormald(x); }
  int isnormal(float x) { return __isnormalf(x); }
  int issubnormal(real x) { return __fpclassifyd(x) == FP_SUBNORMAL; }
  int issubnormal(double x) { return __fpclassifyd(x) == FP_SUBNORMAL; }
  int issubnormal(float x) { return __fpclassifyf(x) == FP_SUBNORMAL; }
  int isinf(real x) { return __isinfd(x); }
  int signbit(real x) { return __signbitd(x); }
  int fpclassify(real x) { return __fpclassifyd(x); }    
  int fpclassify(double x) { return __fpclassifyd(x); }    
  int fpclassify(float x) { return __fpclassifyf(x); }    
} else version (solaris) {
    // for now this is a copy of the darwin stuff (and doesn't work)
  extern (C) {
      // the 'real' versions are declared, but do not actually exist...
      int __isnand(double);
      int __isnanf(float);
      int __isnan(real);
      int __isfinited(double);
      int __isfinitef(float);
      int __isfinite(real);
      int __isnormald(double);
      int __isnormalf(float);
      int __isnormal(real);
      int __fpclassifyd(double);
      int __fpclassifyf(float);
      int __fpclassify(real);
      int __isinfd(double);
      int __isinff(float);
      int __isinf(real);
      int __signbitd(double);
      int __signbitf(float);
      int __signbitl(real);
  }
  
  int isnan(real x) { return __isnand(x); }
  int isfinite(real x) { return __isfinited(x); }
  int isnormal(real x) { return __isnormald(x); }
  int isnormal(double x) { return __isnormald(x); }
  int isnormal(float x) { return __isnormalf(x); }
  int issubnormal(real x) { return __fpclassifyd(x) == FP_SUBNORMAL; }
  int issubnormal(double x) { return __fpclassifyd(x) == FP_SUBNORMAL; }
  int issubnormal(float x) { return __fpclassifyf(x) == FP_SUBNORMAL; }
  int isinf(real x) { return __isinfd(x); }
  int signbit(real x) { return __signbitd(x); }
  int fpclassify(real x) { return __fpclassifyd(x); }    
  int fpclassify(double x) { return __fpclassifyd(x); }    
  int fpclassify(float x) { return __fpclassifyf(x); }    
} else {
    version = Use_FP_Math;
}

version (Use_FP_Math)
{
    import gcc.fpmath;

    int isnan(real x) { return fpclassify(x)==FP_NAN; }
    int isfinite(real x) {
	int r = fpclassify(x);
	return r != FP_NAN && r != FP_INFINITE;
    }
    int isnormal(real x) { return fpclassify(x)==FP_NORMAL; }
    int isnormal(double x) { return fpclassify(x)==FP_NORMAL; }
    int isnormal(float x) { return fpclassify(x)==FP_NORMAL; }
    int issubnormal(real x) { return fpclassify(x) == FP_SUBNORMAL; }
    int issubnormal(double x) { return fpclassify(x) == FP_SUBNORMAL; }
    int issubnormal(float x) { return fpclassify(x) == FP_SUBNORMAL; }
    int isinf(real x) { return fpclassify(x)==FP_INFINITE; }
}

// TODO: configure these
private import std.c.stdio;
extern (C) int ferror(FILE *);
extern (C) int feof(FILE *);
extern (C) void clearerr(FILE *);
extern (C) void rewind(FILE *);
extern (C) int _bufsize(FILE *);
extern (C) int fileno(FILE *);

alias __builtin_snprintf Csnprintf;
alias __builtin_vsnprintf Cvsnprintf;
alias __builtin_snprintf C_snprintf;
alias __builtin_vsnprintf C_vsnprintf;

version (GNU_Have_strtold)
{
    extern (C) real strtold(char*, char**);
    alias strtold cstrtold;
}
else
{
    private extern (C) double strtod(char*, char**);
    extern (D) real cstrtold(char* a, char** b) { return strtod(a, b); }
}
