
version (darwin)
{
    private struct _XFILE {
	byte[gcc.config.FILE_struct_size] opaque;
    }
    const void * stdin  = &__sF;
    const void * stdout = (ubyte*)&__sF + gcc.config.FILE_struct_size;
    const void * stderr = (ubyte*)&__sF + gcc.config.FILE_struct_size * 2;
}
else version (linux)
{
    alias gcc.configext.stdin stdin;
    alias gcc.configext.stdout stdout;
    alias gcc.configext.stderr stderr;
}
else
{
    extern (C) {
	// make these private?
	void * _d_gnu_cbridge_stdin;
	void * _d_gnu_cbridge_stdout;
	void * _d_gnu_cbridge_stderr;
	void _d_gnu_cbridge_init_stdio();
    }
    alias _d_gnu_cbridge_stdin stdin;
    alias _d_gnu_cbridge_stdout stdout;
    alias _d_gnu_cbridge_stderr stderr;

    static this() {
	_d_gnu_cbridge_init_stdio();
    }
}

// TODO: configurate ?  This is a real mess...
version (linux) {
  // on X86, can use original DMD code, but not on other CPUs...
    version (None) {
      enum {
	FP_NAN,
	FP_INFINITE,
	FP_ZERO,
	FP_SUBNORMAL,
	FP_NORMAL
      }
    }

    extern (C) {
	int __isnan(double);
	int __isnanf(float);
	int __isnanl(real);
	int __isfinite(double);
	int __isfinitef(float);
	int __isfinitel(real);
	int __fpclassify(double);
	int __fpclassifyf(float);
	int __fpclassifyl(real);
	int __isinf(double);
	int __isinff(float);
	int __isinfl(real);
	int __signbit(double);
	int __signbitf(float);
	int __signbitl(real);
    }
  
    int isnan(real x) { return __isnanl(x); }
    int isfinite(real x) { return __isfinitel(x); }
    int isnormal(real x) { return __fpclassifyl(x) == FP_NORMAL; }
    int isnormal(double x) { return __fpclassify(x) == FP_NORMAL; }
    int isnormal(float x) { return __fpclassifyf(x) == FP_NORMAL; }
    int issubnormal(real x) { return __fpclassifyl(x) == FP_SUBNORMAL; }
    int issubnormal(double x) { return __fpclassify(x) == FP_SUBNORMAL; }
    int issubnormal(float x) { return __fpclassifyf(x) == FP_SUBNORMAL; }
    int isinf(real x) { return __isinfl(x); }
    int signbit(real x) { return __signbitl(x); }
    int fpclassify(real x) { return __fpclassifyl(x); }    
    int fpclassify(double x) { return __fpclassify(x); }    
    int fpclassify(float x) { return __fpclassifyf(x); }    

} else version (darwin) {
    // could use direct ieee stuff, but long double/real is a problem
    version (None) {
	enum {
		FP_NAN          = 1,                   /*      NaN                    */
		FP_INFINITE     = 2,                   /*      + or - infinity        */
		FP_ZERO         = 3,                   /*      + or - zero            */
		FP_NORMAL       = 4,                   /*      all normal numbers     */
		FP_SUBNORMAL    = 5                    /*      denormal numbers       */
	}
    }
    
  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 {
    // %%TODO: slightly better: test which of __fpclassify[fdl<null>] exist
    // and use those.  Could do the same with __is
    extern (C) {
	int _d_gnu_cbridge_fpclassifyl(real);
	int _d_gnu_cbridge_fpclassifyd(double);
	int _d_gnu_cbridge_fpclassifyf(float);
	int _d_gnu_cbridge_signbitl(real);
	int _d_gnu_cbridge_signbitd(double);
	int _d_gnu_cbridge_signbitf(float);
    }
    int isnan(real x) { return _d_gnu_cbridge_fpclassifyl(x)==FP_NAN; }
    int isfinite(real x) {
	int r = _d_gnu_cbridge_fpclassifyl(x);
	return r != FP_NAN && r != FP_INFINITE;
    }
    int isnormal(real x) { return _d_gnu_cbridge_fpclassifyl(x)==FP_NORMAL; }
    int isnormal(double x) { return _d_gnu_cbridge_fpclassifyd(x)==FP_NORMAL; }
    int isnormal(float x) { return _d_gnu_cbridge_fpclassifyf(x)==FP_NORMAL; }
    int issubnormal(real x) { return _d_gnu_cbridge_fpclassifyl(x) == FP_SUBNORMAL; }
    int issubnormal(double x) { return _d_gnu_cbridge_fpclassifyd(x) == FP_SUBNORMAL; }
    int issubnormal(float x) { return _d_gnu_cbridge_fpclassifyf(x) == FP_SUBNORMAL; }
    int isinf(real x) { return _d_gnu_cbridge_fpclassifyl(x)==FP_INFINITE; }
    int signbit(real x) { return _d_gnu_cbridge_signbitl(x)==FP_NAN; }
    int fpclassify(real x) { return _d_gnu_cbridge_fpclassifyl(x); }
    int fpclassify(double x) { return _d_gnu_cbridge_fpclassifyd(x); }
    int fpclassify(float x) { return _d_gnu_cbridge_fpclassifyf(x); }
}

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

alias ubyte* Cva_list; // 'va_list' causes problems later...
alias __builtin_va_start Cva_start;
