// 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...


// If long double functions are present, just alias
// to the __builtin_ version.  This may not do the right thing (TODO)
extern (C) { // prob doesn't matter..
alias __builtin_acosl acosl;
alias __builtin_asinl asinl;
alias __builtin_atanl atanl;
alias __builtin_atan2l atan2l;
alias __builtin_cosl cosl;
alias __builtin_sinl sinl;
alias __builtin_tanl tanl;
alias __builtin_acoshl acoshl;
alias __builtin_asinhl asinhl;
alias __builtin_atanhl atanhl;
alias __builtin_coshl coshl;
alias __builtin_sinhl sinhl;
alias __builtin_tanhl tanhl;
alias __builtin_expl expl;
alias __builtin_exp2l exp2l;
alias __builtin_expm1l expm1l;
alias __builtin_frexpl frexpl;
alias __builtin_ilogbl ilogbl;
alias __builtin_ldexpl ldexpl;
alias __builtin_logl logl;
alias __builtin_log10l log10l;
alias __builtin_log1pl log1pl;
alias __builtin_log2l log2l;
alias __builtin_logbl logbl;
alias __builtin_modfl modfl;
alias __builtin_scalbnl scalbnl;
alias __builtin_scalblnl scalblnl;
alias __builtin_cbrtl cbrtl;
alias __builtin_fabsl fabsl;
alias __builtin_hypotl hypotl;
alias __builtin_powl powl;
alias __builtin_sqrtl sqrtl;
alias __builtin_erfl erfl;
alias __builtin_erfcl erfcl;
alias __builtin_lgammal lgammal;
alias __builtin_tgammal tgammal;
alias __builtin_ceill ceill;
alias __builtin_floorl floorl;
alias __builtin_nearbyintl nearbyintl;
alias __builtin_rintl rintl;
alias __builtin_lrintl lrintl;
alias __builtin_llrintl llrintl;
alias __builtin_roundl roundl;
alias __builtin_lroundl lroundl;
alias __builtin_llroundl llroundl;
alias __builtin_truncl truncl;
alias __builtin_fmodl fmodl;
alias __builtin_remainderl remainderl;
alias __builtin_remquol remquol;
alias __builtin_copysignl copysignl;
//alias __builtin_nanl nanl;
real nanl(char *);
alias __builtin_nextafterl nextafterl;
alias __builtin_nexttowardl nexttowardl;
alias __builtin_fdiml fdiml;
alias __builtin_fmaxl fmaxl;
alias __builtin_fminl fminl;
alias __builtin_fmal fmal;

alias __builtin_sqrt sqrt;
//alias __builtin_sqrtf sqrtf;// needs an extra step
}

alias __builtin_sqrtf sqrtf;

//   C stdio config for std.stdio
const bool Have_fwide = 1;
const bool Have_getdelim = 1;
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 = 304;
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); }
}
