diff --git a/src/sprtf.c b/src/sprtf.c new file mode 100644 index 0000000..44c2ca6 --- /dev/null +++ b/src/sprtf.c @@ -0,0 +1,440 @@ +/* + * SPRTF - Log output utility + * + * Author: Geoff R. McLane + * License: GPL v2 (or later at your choice) + * + * Revision 1.0.1 2012/11/06 13:01:25 geoff + * Revision 1.0.0 2012/10/17 00:00:00 geoff + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, US + * + */ + +// Module: sprtf.cxx +// Debug log file output +#include // fopen()... +#include // strcpy +#include // va_start, va_end, ... +#ifdef _MSC_VER +#include +#include +#else /* !_MSC_VER */ +#include // gettimeoday(), struct timeval,... +#endif /* _MSC_VER y/n */ +#include +#include // for exit() in unix +#include "sprtf.h" + +#ifdef _MSC_VER +#ifndef _CRT_SECURE_NO_DEPRECATE +#define _CRT_SECURE_NO_DEPRECATE +#endif // #ifndef _CRT_SECURE_NO_DEPRECATE +#pragma warning( disable:4996 ) +#else +#define strcmpi strcasecmp +#endif + +#ifndef MX_ONE_BUF +#define MX_ONE_BUF 1024 +#endif +#ifndef MX_BUFFERS +#define MX_BUFFERS 1024 +#endif + +static char _s_strbufs[MX_ONE_BUF * MX_BUFFERS]; +static int iNextBuf = 0; + +char *GetNxtBuf() +{ + iNextBuf++; + if(iNextBuf >= MX_BUFFERS) + iNextBuf = 0; + return &_s_strbufs[MX_ONE_BUF * iNextBuf]; +} + +#define MXIO 512 +#ifdef _MSC_VER // use local log +static char def_log[] = "tempex.txt"; +#else +static char def_log[] = "ex.log"; +#endif +static char logfile[264] = "\0"; +static FILE * outfile = NULL; +static int addsystime = 0; +static int addsysdate = 0; +static int addstdout = 1; +static int addflush = 1; +static int add2screen = 0; +static int add2listview = 0; +static int append_to_log = 0; + +#ifndef VFP +#define VFP(a) ( a && ( a != (FILE *)-1 ) ) +#endif + +int add_list_out( int val ) +{ + int i = add2listview; + add2listview = val; + return i; +} + +int add_std_out( int val ) +{ + int i = addstdout; + addstdout = val; + return i; +} + +int add_screen_out( int val ) +{ + int i = add2screen; + add2screen = val; + return i; +} + + +int add_sys_time( int val ) +{ + int i = addsystime; + addsystime = val; + return i; +} + +int add_sys_date( int val ) +{ + int i = addsysdate; + addsysdate = val; + return i; +} + + +int add_append_log( int val ) +{ + int i = append_to_log; + append_to_log = val; + return i; +} + + +#ifdef _MSC_VER +static const char *mode = "wb"; // in window sprtf looks after the line endings +#else +static const char *mode = "w"; +#endif + +int open_log_file( void ) +{ + if (logfile[0] == 0) + strcpy(logfile,def_log); + if (append_to_log) { +#ifdef _MSC_VER + mode = "ab"; // in window sprtf looks after the line endings +#else + mode = "a"; +#endif + } + outfile = fopen(logfile, mode); + if( outfile == 0 ) { + outfile = (FILE *)-1; + sprtf("ERROR: Failed to open log file [%s] ...\n", logfile); + exit(1); /* failed */ + return 0; /* failed */ + } + return 1; /* success */ +} + +void close_log_file( void ) +{ + if( VFP(outfile) ) { + fclose(outfile); + } + outfile = NULL; +} + +char * get_log_file( void ) +{ + if (logfile[0] == 0) + strcpy(logfile,def_log); + if (outfile == (FILE *)-1) // disable the log file + return (char *)"none"; + return logfile; +} + +void set_log_file( char * nf, int open ) +{ + if (logfile[0] == 0) + strcpy(logfile,def_log); + if ( nf && *nf && strcmpi(nf,logfile) ) { + close_log_file(); // remove any previous + strcpy(logfile,nf); // set new name + if (strcmp(logfile,"none") == 0) { // if equal 'none' + outfile = (FILE *)-1; // disable the log file + } else if (open) { + open_log_file(); // and open it ... anything previous written is 'lost' + } else + outfile = 0; // else set 0 to open on first write + } +} + +#ifdef _MSC_VER +int gettimeofday(struct timeval *tp, void *tzp) +{ +#ifdef WIN32 + struct _timeb timebuffer; + _ftime(&timebuffer); + tp->tv_sec = (long)timebuffer.time; + tp->tv_usec = timebuffer.millitm * 1000; +#else + tp->tv_sec = time(NULL); + tp->tv_usec = 0; +#endif + return 0; +} + +#endif // _MSC_VER + +void add_date_stg( char *ps, struct timeval *ptv ) +{ + time_t curtime; + struct tm * ptm; + curtime = (ptv->tv_sec & 0xffffffff); + ptm = localtime(&curtime); + if (ptm) { + strftime(EndBuf(ps),128,"%Y/%m/%d",ptm); + } +} + +void add_time_stg( char *ps, struct timeval *ptv ) +{ + time_t curtime; + struct tm * ptm; + curtime = (ptv->tv_sec & 0xffffffff); + ptm = localtime(&curtime); + if (ptm) { + strftime(EndBuf(ps),128,"%H:%M:%S",ptm); + } +} + +char *get_date_stg() +{ + char *ps; + struct timeval tv; + gettimeofday( (struct timeval *)&tv, (struct timezone *)0 ); + ps = GetNxtBuf(); + *ps = 0; + add_date_stg( ps, &tv ); + return ps; +} + +char *get_time_stg() +{ + char *ps; + struct timeval tv; + gettimeofday( (struct timeval *)&tv, (struct timezone *)0 ); + ps = GetNxtBuf(); + *ps = 0; + add_time_stg( ps, &tv ); + return ps; +} + +char *get_date_time_stg() +{ + char *ps; + struct timeval tv; + gettimeofday( (struct timeval *)&tv, (struct timezone *)0 ); + ps = GetNxtBuf(); + *ps = 0; + add_date_stg( ps, &tv ); + strcat(ps," "); + add_time_stg( ps, &tv ); + return ps; +} + +static void oi( char * psin ) +{ + int len, w; + char * ps = psin; + if (!ps) + return; + + len = (int)strlen(ps); + if (len) { + + if( outfile == 0 ) { + open_log_file(); + } + if( VFP(outfile) ) { + char *tb; + if (addsysdate) { + tb = GetNxtBuf(); + len = sprintf( tb, "%s - %s", get_date_time_stg(), ps ); + ps = tb; + } else if( addsystime ) { + tb = GetNxtBuf(); + len = sprintf( tb, "%s - %s", get_time_stg(), ps ); + ps = tb; + } + + w = (int)fwrite( ps, 1, len, outfile ); + if( w != len ) { + fclose(outfile); + outfile = (FILE *)-1; + sprtf("WARNING: Failed write to log file [%s] ...\n", logfile); + exit(1); + } else if (addflush) { + fflush( outfile ); + } + } + + if( addstdout ) { + fwrite( ps, 1, len, stdout ); + } +#ifdef ADD_LISTVIEW + if (add2listview) { + LVInsertItem(ps); + } +#endif // ADD_LISTVIEW +#ifdef ADD_SCREENOUT + if (add2screen) { + Add_String(ps); // add string to screen list + } +#endif // #ifdef ADD_SCREENOUT + } +} + +#ifdef _MSC_VER +// service to ensure line endings in windows only +static void prt( char * ps ) +{ + static char _s_buf[1024]; + char * pb = _s_buf; + size_t i, j, k; + char c, d; + i = strlen(ps); + k = 0; + d = 0; + if(i) { + k = 0; + d = 0; + for( j = 0; j < i; j++ ) { + c = ps[j]; + if( c == 0x0d ) { + if( (j+1) < i ) { + if( ps[j+1] != 0x0a ) { + pb[k++] = c; + c = 0x0a; + } + } else { + pb[k++] = c; + c = 0x0a; + } + } else if( c == 0x0a ) { + if( d != 0x0d ) { + pb[k++] = 0x0d; + } + } + pb[k++] = c; + d = c; + if( k >= MXIO ) { + pb[k] = 0; + oi(pb); + k = 0; + } + } // for length of string + if( k ) { + //if( ( gbCheckCrLf ) && + // ( d != 0x0a ) ) { + // add Cr/Lf pair + //pb[k++] = 0x0d; + //pb[k++] = 0x0a; + //pb[k] = 0; + //} + pb[k] = 0; + oi( pb ); + } + } +} +#endif // #ifdef _MSC_VER + +int direct_out_it( char *cp ) +{ +#ifdef _MSC_VER + prt(cp); +#else + oi(cp); +#endif + return (int)strlen(cp); +} + +// STDAPI StringCchVPrintf( OUT LPTSTR pszDest, +// IN size_t cchDest, IN LPCTSTR pszFormat, IN va_list argList ); +int MCDECL sprtf( const char *pf, ... ) +{ + static char _s_sprtfbuf[M_MAX_SPRTF+4]; + char * pb = _s_sprtfbuf; + int i; + va_list arglist; + va_start(arglist, pf); + i = vsprintf( pb, pf, arglist ); + va_end(arglist); +#ifdef _MSC_VER + prt(pb); // ensure CR/LF +#else + oi(pb); +#endif + return i; +} + +#ifdef UNICODE +// WIDE VARIETY +static void wprt( PTSTR ps ) +{ + static char _s_woibuf[1024]; + char * cp = _s_woibuf; + int len = (int)lstrlen(ps); + if(len) { + int ret = WideCharToMultiByte( CP_ACP, // UINT CodePage, // code page + 0, // DWORD dwFlags, // performance and mapping flags + ps, // LPCWSTR lpWideCharStr, // wide-character string + len, // int cchWideChar, // number of chars in string. + cp, // LPSTR lpMultiByteStr, // buffer for new string + 1024, // int cbMultiByte, // size of buffer + NULL, // LPCSTR lpDefaultChar, // default for unmappable chars + NULL ); // LPBOOL lpUsedDefaultChar // set when default char used + //oi(cp); + prt(cp); + } +} + +int MCDECL wsprtf( PTSTR pf, ... ) +{ + static WCHAR _s_sprtfwbuf[1024]; + PWSTR pb = _s_sprtfwbuf; + int i = 1; + va_list arglist; + va_start(arglist, pf); + *pb = 0; + StringCchVPrintf(pb,1024,pf,arglist); + //i = vswprintf( pb, pf, arglist ); + va_end(arglist); + wprt(pb); + return i; +} + +#endif // #ifdef UNICODE + +// eof - sprtf.cxx diff --git a/src/sprtf.h b/src/sprtf.h new file mode 100644 index 0000000..23db8ae --- /dev/null +++ b/src/sprtf.h @@ -0,0 +1,75 @@ +/* + * SPRTF - Log output utility + * + * Author: Geoff R. McLane + * License: GPL v2 (or later at your choice) + * + * Revision 1.0.1 2012/11/06 13:01:25 geoff + * Revision 1.0.0 2012/10/17 00:00:00 geoff + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, US + * + */ + +// Module: sprtf.hxx +// Debug log file output +#ifndef _SPRTF_HXX_ +#define _SPRTF_HXX_ +#ifdef __cplusplus +extern "C" { +#endif +#ifdef _MSC_VER +#define MCDECL _cdecl +#else +#define MCDECL +#endif + +extern int add_std_out( int val ); +extern int add_sys_time( int val ); +extern int add_sys_date( int val ); + +extern int add_screen_out( int val ); +extern int add_list_out( int val ); +extern int add_append_log( int val ); + +extern int open_log_file( void ); +extern void close_log_file( void ); +extern void set_log_file( char * nf, int open ); +extern char * get_log_file( void ); + +extern int MCDECL sprtf( const char *pf, ... ); +#define M_MAX_SPRTF 2048 +extern int direct_out_it( char *cp ); + +extern char *GetNxtBuf(); + +#define EndBuf(a) ( a + strlen(a) ) + +extern char *get_date_stg(); +extern char *get_time_stg(); +extern char *get_date_time_stg(); +#ifdef _MSC_VER +extern int gettimeofday(struct timeval *tp, void *tzp); +#endif + +#ifndef SPRTF +#define SPRTF sprtf +#endif + +#ifdef __cplusplus +} +#endif +#endif // #ifndef _SPRTF_HXX_ +// oef - sprtf.hxx