240 lines
4.9 KiB
C
240 lines
4.9 KiB
C
/* switch off ANSI_C_SOURCE for VMS-extended fopen, even when compiling with /ANSI */
|
|
#ifdef __VMS
|
|
#ifdef __HIDE_FORBIDDEN_NAMES
|
|
#undef __HIDE_FORBIDDEN_NAMES
|
|
#include <stdio.h>
|
|
#define __HIDE_FORBIDDEN_NAMES
|
|
#else
|
|
#include <stdio.h>
|
|
#endif
|
|
#else
|
|
#include <stdio.h>
|
|
#endif
|
|
|
|
#include <stdlib.h>
|
|
#include <sys/time.h>
|
|
#include <sys/timeb.h>
|
|
#include <string.h>
|
|
#include <stdarg.h>
|
|
#include <assert.h>
|
|
#include "coc_logfile.h"
|
|
#include "err_handling.h"
|
|
#include "str_util.h"
|
|
|
|
static FILE *fil=NULL;
|
|
static char lnam[256]="", filnam[256]="";
|
|
static char ebuf[20000]="";
|
|
static char *eptr=&ebuf[0];
|
|
static int lastStamp=0;
|
|
static int notDated=0;
|
|
static int logMask=0;
|
|
static int wrtMask=0;
|
|
|
|
int ftime (struct timeb *__timeptr); /* for some reason not defined in timeb.h with flag -std1 */
|
|
|
|
static int logfileStd;
|
|
static int dirty, writeAll;
|
|
|
|
void logfileOpen(int first) {
|
|
struct tm *tim;
|
|
struct timeb btim;
|
|
|
|
if (logfileStd) {
|
|
fil=stdout;
|
|
return;
|
|
}
|
|
assert(fil==NULL);
|
|
if (first) {
|
|
ftime(&btim);
|
|
tim=localtime(&btim.time);
|
|
if (notDated) {
|
|
if (lnam[0]=='\0') {
|
|
str_copy(filnam, "test.log");
|
|
} else {
|
|
str_copy(filnam, lnam);
|
|
str_append(filnam, ".log");
|
|
}
|
|
} else {
|
|
sprintf(filnam, "%s%04d-%02d-%02d.log", lnam, tim->tm_year+1900, tim->tm_mon+1, tim->tm_mday);
|
|
}
|
|
} else {
|
|
assert(filnam[0]!='\0');
|
|
}
|
|
#ifdef __VMS
|
|
if (first && notDated) {
|
|
fil=fopen(filnam, "w", "SHR=UPD"); /* new version at restart */
|
|
} else {
|
|
fil=fopen(filnam, "a", "SHR=UPD");
|
|
}
|
|
#else
|
|
if (first && notDated) {
|
|
fil=fopen(filnam, "w"); /* overwrite at restart */
|
|
} else {
|
|
fil=fopen(filnam, "a");
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void logfileInit(char *path, int nodate, int use_stdout, int write_all) {
|
|
str_copy(lnam, path);
|
|
lastStamp=-1;
|
|
logfileStd=use_stdout;
|
|
writeAll=write_all;
|
|
notDated=nodate;
|
|
logfileOpen(1);
|
|
}
|
|
|
|
void logfileOut(int mask, const char *fmt, ...)
|
|
{ va_list ap;
|
|
|
|
assert(mask>0 && mask<32);
|
|
va_start(ap, fmt);
|
|
|
|
if (writeAll) {
|
|
#ifdef __VMS
|
|
if (fil==NULL) logfileOpen(0);
|
|
#endif
|
|
vfprintf(fil, fmt, ap);
|
|
wrtMask=LOG_ALL;
|
|
} else {
|
|
if (eptr!=NULL) {
|
|
if (eptr-ebuf > sizeof(ebuf)-512) {
|
|
sprintf(eptr, "... buffer full ... \1\1");
|
|
eptr=NULL;
|
|
} else {
|
|
vsprintf(eptr, fmt, ap);
|
|
assert(NULL==strchr(eptr, '\1'));
|
|
eptr+=strlen(eptr);
|
|
eptr[0]='\1'; /* put \1 as separator between blocks */
|
|
eptr[1]=mask;
|
|
eptr[2]='\0';
|
|
eptr+=2;
|
|
}
|
|
}
|
|
wrtMask=wrtMask | mask;
|
|
}
|
|
va_end(ap);
|
|
}
|
|
|
|
void logfileMask(int mask) {
|
|
logMask=logMask | mask;
|
|
}
|
|
|
|
void logfileStamp(void) {
|
|
struct tm *tim;
|
|
struct timeb btim;
|
|
int stamp;
|
|
|
|
ftime(&btim);
|
|
tim=localtime(&btim.time);
|
|
stamp=tim->tm_hour*60+tim->tm_min;
|
|
if (stamp!=lastStamp) {
|
|
if (stamp<lastStamp) { /* time smaller than last time -> new day -> new logfile */
|
|
if (fil!=NULL) { fclose(fil); fil=NULL; }
|
|
logfileOpen(1);
|
|
}
|
|
#ifdef __VMS
|
|
else if (fil==NULL) logfileOpen(0);
|
|
#endif
|
|
lastStamp=stamp;
|
|
fprintf(fil, "--- %02d:%02d:%02d ---\n", tim->tm_hour, tim->tm_min, tim->tm_sec);
|
|
dirty=0;
|
|
}
|
|
}
|
|
|
|
void logfileWrite0(int mask) {
|
|
char *s, *next;
|
|
|
|
logMask=logMask | mask;
|
|
if (dirty) logfileStamp(); /* there was something written since last time */
|
|
|
|
s=ebuf;
|
|
if (writeAll || *s!='\0' && wrtMask & logMask) {
|
|
logfileStamp(); /* write stamp before write something */
|
|
next=strchr(s, '\1');
|
|
while (next!=NULL) {
|
|
*next='\0';
|
|
next++;
|
|
if (*next & logMask) {
|
|
fprintf(fil, "%s", s);
|
|
dirty=1;
|
|
}
|
|
s=next+1;
|
|
next=strchr(s, '\1');
|
|
}
|
|
}
|
|
ebuf[0]='\0';
|
|
eptr=&ebuf[0];
|
|
logMask=0;
|
|
wrtMask=0;
|
|
}
|
|
|
|
void logfileWrite(int mask) {
|
|
|
|
#ifdef __VMS
|
|
if (fil==NULL) logfileOpen(0);
|
|
#endif
|
|
logfileWrite0(mask);
|
|
#ifdef __VMS
|
|
if (!logfileStd) { fclose(fil); fil=NULL; }
|
|
#else
|
|
fflush(fil);
|
|
#endif
|
|
|
|
}
|
|
|
|
void logfileShowErr(char *text)
|
|
{
|
|
#ifdef __VMS
|
|
if (fil==NULL) logfileOpen(0);
|
|
#endif
|
|
logfileWrite0(LOG_ALL); /* write all */
|
|
ErrWrite(text);
|
|
#ifdef __VMS
|
|
if (!logfileStd) { fclose(fil); fil=NULL; }
|
|
#else
|
|
fflush(fil);
|
|
#endif
|
|
}
|
|
|
|
void logfileClose()
|
|
{
|
|
#ifdef __VMS
|
|
if (fil==NULL) logfileOpen(0);
|
|
#endif
|
|
logfileWrite0(LOG_MAIN+LOG_WARN);
|
|
lastStamp-=1;
|
|
logfileStamp();
|
|
if (fil!=NULL) { fclose(fil); fil=NULL; }
|
|
filnam[0]='\0';
|
|
}
|
|
|
|
void logfileOutBuf(int mask, Str_Buf *buf)
|
|
{ char str[256];
|
|
int rd0, sep;
|
|
|
|
rd0=buf->rdpos;
|
|
if (buf->rdpos < 0 || buf->rdpos >= buf->dsize
|
|
|| buf->wrpos < 0 || buf->wrpos >= buf->dsize) {
|
|
logfileOut(mask, "<buffer corrupt>"); return;
|
|
}
|
|
sep=0;
|
|
while (buf->rdpos < buf->wrpos) {
|
|
str_get_str(buf, str);
|
|
if (buf->sep=='\0') {
|
|
if (sep) logfileOut(mask, " ");
|
|
if (*str=='\0') {
|
|
logfileOut(mask, ".");
|
|
} else {
|
|
logfileOut(mask, "%s", str);
|
|
}
|
|
sep=1;
|
|
} else {
|
|
if (sep) logfileOut(mask, "%c", buf->sep);
|
|
logfileOut(mask, "%s", str);
|
|
sep=1;
|
|
}
|
|
}
|
|
buf->rdpos=rd0;
|
|
}
|