/* #Specification: FILE_CFG / principles Originally, the CONFIG_FILE::fopen() function was returning a FILE pointer and client code all over the place where using stdio functions on it, including fclose(). This was not a problem, except for fclose(). We had control over the "open" process, but could not enhance the process at close time. The FILE_CFG works (from outside) like a FILE object (from stdio.h). All stdio function are overloaded to work with FILE_CFG. Our goal is to overload the fclose stdio function so we know when a CONFIG_FILE is updated. The function CONFIG_FILE::fopen return a FILE_CFG pointer. To overload fclose, we have to overload few things as well: fputs, fprintf , etc ...). */ #include #include #include "misc.h" class FILE_CFG{ public: FILE *f; const CONFIG_FILE *cf; bool relinktmp; /*~PROTOBEG~ FILE_CFG */ public: FILE_CFG (FILE *_f, const CONFIG_FILE *_cf); /*~PROTOEND~ FILE_CFG */ }; PUBLIC FILE_CFG::FILE_CFG( FILE *_f, const CONFIG_FILE *_cf) { f = _f; cf = _cf; relinktmp = false; } void filecfg_setrelink (FILE_CFG *c) { if (c != NULL) c->relinktmp = true; } FILE_CFG *filecfg_new (FILE *f, const CONFIG_FILE *cf) { FILE_CFG *ret = NULL; if (f != NULL) ret = new FILE_CFG (f,cf); return ret; } /* Replacement for stdio function using FILE_CFG */ int fclose (FILE_CFG *fout) { int ret = fclose (fout->f); if (ret != -1 && fout->cf != NULL && fout->relinktmp){ fout->cf->relink_tmp(); } delete fout; return ret; } /* Replacement for stdio function using FILE_CFG */ int fputs (const char *s, FILE_CFG *fout) { return fputs (s,fout->f); } /* Replacement for stdio function using FILE_CFG */ int fputc (char c, FILE_CFG *fout) { return fputc (c,fout->f); } /* Replacement for stdio function using FILE_CFG */ char *fgets (char *s, int size, FILE_CFG *fout) { return fgets (s,size,fout->f); } /* Replacement for stdio function using FILE_CFG */ int fprintf (FILE_CFG *fout, const char *ctl, ...) { va_list list; va_start (list,ctl); int ret = vfprintf (fout->f,ctl,list); va_end (list); return ret; } /* Replacement for stdio function using FILE_CFG */ int fwrite (const void *ptr, size_t size, size_t n, FILE_CFG *fout) { return fwrite (ptr,size,n,fout->f); } /* Replacement for stdio function using FILE_CFG */ int fread (void *ptr, size_t size, size_t n, FILE_CFG *fout) { return fread (ptr,size,n,fout->f); } void comment_write (const SSTRING &str, FILE_CFG *fout, char comchar) { comment_write (str,fout->f,comchar); } void comment_write (const SSTRING &str, FILE_CFG *fout) { comment_write (str,fout->f); } const char *fgets_comments ( char buf[], int size, FILE_CFG *fin, SSTRING &comments, char comchar) { return fgets_comments (buf,size,fin->f,comments,comchar); } const char *fgets_comments ( char buf[], int size, FILE_CFG *fin, SSTRING &comments) { return fgets_comments (buf,size,fin->f,comments); } char *fgets_strip ( char *buf, int sizebuf, FILE_CFG *fin, char contcar, char comcar, int *noline) { return fgets_strip(buf,sizebuf,fin->f,contcar,comcar,noline); } char *fgets_strip ( char *buf, int sizebuf, FILE_CFG *fin, int *noline) { return fgets_strip(buf,sizebuf,fin->f,noline); } int fgets_cont (char *buf, int size, FILE_CFG *fin, bool cont) { return fgets_cont (buf,size,fin->f,cont); } int fgets_cont (char *buf, int size, FILE_CFG *fin) { return fgets_cont (buf,size,fin->f); } char *fgets_long (char *&line, int &len, FILE_CFG *fin) { return fgets_long (line,len,fin->f); } /* Replacement for stdio function using FILE_CFG */ int fflush (FILE_CFG *fout) { return fflush(fout->f); } /* Replacement for stdio function using FILE_CFG */ int fscanf (FILE_CFG *fin, const char *ctl, ...) { va_list list; va_start (list,ctl); int ret = vfscanf (fin->f,ctl,list); va_end (list); return ret; } /* Replacement for stdio function using FILE_CFG */ void rewind (FILE_CFG *f) { rewind (f->f); } /* Replacement for stdio function using FILE_CFG */ long ftell (FILE_CFG *f) { return ftell (f->f); } /* Replacement for stdio function using FILE_CFG */ int fseek (FILE_CFG *f, long offset, int whence) { return fseek (f->f,offset,whence); } /* Replacement for stdio function using FILE_CFG */ FILE_CFG *fopen_cfg (const char *fname, const char *mode) { FILE *f = fopen(fname,mode); FILE_CFG *ret = NULL; if (f != NULL){ ret = new FILE_CFG (f,NULL); } return ret; } /* Replacement for stdio function using FILE_CFG */ int feof (FILE_CFG *f) { return feof(f->f); } /* Replacement for stdio function using FILE_CFG */ int fgetc (FILE_CFG *f) { return getc(f->f); } /* Replacement for stdio function using FILE_CFG */ int fputc (int c, FILE_CFG *f) { return putc (c,f->f); } /* Replacement for stdio function using FILE_CFG */ int fileno (FILE_CFG *f) { return fileno(f->f); } /* Return the original FILE handle associated with a FILE_CFG */ FILE *filecfg_tofile (FILE_CFG *f) { return f != NULL ? f->f : NULL; }