#define USING_DFOPEN 1
#ifdef WIN32
#include <io.h>
#else
#include <sys/stat.h>
#endif

#ifdef WIN32
#if (_MSC_VER > 1900)
#include <stdint.h>
#else
#include "mystdint.h"
#endif
#else
#include <stdint.h>
#endif 

#include "lib_spawn.h"

int dfopen_handle_opened(FILE *f,  char *filename, char *srcfile, int srcline) ;
void dfopen_init_check(int (*vcheck)( char *file, int line));
int dfopen_mutex_wait(int line);
void dfopen_mutex_release(void);
int dfopen_log_fd(FILE *f);
int is_disk_full(void);

int dfopen_set_mutex(int (*cb)(int vm, int isget, int seconds,char *file, int line), int m);
void dfopen_init(int (*vemsg)( const char *format ,...));
FILE *dfopen( const char *filename, const char *mode , const char *srcfile, int srcline, const char *fnname);
int dfclose( FILE *stream, char *closefile, int closeline, const char *fnname );
int dfopen_die(char *reason, char *src, int line, int n);
void dfopen_exit(void);
void dfopen_dump(char *dumpfile);
FILE *dftmpfile(void);
char *dfopen_fname(FILE *f);
int dfopen_hist_info(IHANDLE handle, int isopen, int logonly, char *filename, int line, char *info);
void dfopen_enable_timing(int x);
int dfopen_history(int handle, char *fname, char *etext);

#define fopen(a,b) dfopen(a,b,__FILE__,__LINE__,__FUNCTION__)
//#define rename(a,b) dfrename(a,b,__FILE__,__LINE__)
#define fclose(x) dfclose(x,__FILE__,__LINE__,__FUNCTION__)
#define tmpfile() dftmpfile()

size_t df_fread(void *data, size_t size, size_t n , FILE *f, char *source, int line, const char *fnname);
size_t df_fwrite(const void *data, size_t size, size_t n , FILE *f, char *source, int line, const char *fnname);
char *df_fgets(char *a, int b, FILE *c, char *source, int line, const  char *fnname);
int /*@printflike@*/ df_fprintf(char *src, int line, const  char *fnname, FILE *f,const char * arg_list, ...);

/*
#ifdef WIN32
#ifndef __BORLANDC__
#define _stat stat
#define _fstat fstat
#endif
#endif
*/

int fd_fstat(int handle, struct stat *buffer, char *source, int line);
int fd_stat(const char *path, struct stat *buffer, char *source, int line);
#ifndef my_stat
int my_stat(const char *path, struct stat *buffer);
#endif
#define my_fstat(a,b) fd_fstat(a,b,__FILE__,__LINE__)
#define my_stat(a,b) fd_stat(a,b,__FILE__,__LINE__)

#ifdef WIN32
#ifdef _findfirst 
#undef _findfirst
#endif
#ifdef _findnext
#undef _findnext
#endif
intptr_t fd_findfirst( char *filespec, struct _finddata_t *fileinfo , char *source, int line);
int fd_findnext(intptr_t handle, struct _finddata_t *fileinfo , char *source, int line);
#define _findfirst(a,b) fd_findfirst(a,b,__FILE__,__LINE__)
#define _findnext(a,b) fd_findnext(a,b,__FILE__,__LINE__)
#endif 

int df_fprintf_src(char *src, int line);

#ifdef __BORLANDC__
#define __FUNCTION__ "borlandc_fn"
#endif


#define fread(a,b,c,d) df_fread(a,b,c,d,__FILE__,__LINE__,__FUNCTION__)
#define fwrite(a,b,c,d) df_fwrite(a,b,c,d,__FILE__,__LINE__,__FUNCTION__)
#define fgets(a,b,c) df_fgets(a,b,c,__FILE__,__LINE__,__FUNCTION__)
// #define fprintf (df_fprintf_src(__FILE__,__LINE__),df_fprintf)
#ifdef WIN32
#ifndef __BORLANDC__
// test without fprintf over-ridden
//#define fprintf(f,format, ...) df_fprintf (__FILE__,__LINE__,__FUNCTION__,f,format, __VA_ARGS__)
#endif
#endif



void get_dfopen_list(void *param, void (*print_line)(void *param, char *line));

void dfopen_init(int (*vemsg)( const char *format ,...));
void dfopen_exit(void);

int dfopen_count(char *reason);
void dfopen_set_report(int (*my_report)(char *reason)) ;
void dfopen_die_limit(void);
int dfopen_dump_stats(void);
int dfrename(const char *a, const char *b, char *file, int line);

FILE *real_fopen(const char *file, const char *mode);
int real_fclose(FILE *f);
void dfopen_set_die(int (*my_die_fn)(char *reason));
