AmiTimeKeeper/log.c

248 lines
5.8 KiB
C

/*-
* Copyright (c) 2017-2018 Carsten Sonne Larsen <cs@innolan.net>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "config.h"
#include "log.h"
#include "mem.h"
#include <stdarg.h>
#define MAXLOGLINESIZE 255
enum LogSeverity
{
ErrorMessage = 5,
WarningMessage = 10,
InfoMessage = 20,
TraceMessage = 30
};
struct LogEntry
{
enum LogSeverity level;
char *line;
struct LogEntry *next;
};
static bool logDisabled = false;
static bool bufferLog = false;
static BPTR logFile = NULL;
static struct LogEntry *firstEntry = NULL;
static struct LogEntry *lastEntry = NULL;
void OpenLogFile(void)
{
BPTR lock;
bool deleteFirst = false;
if (Globals->Settings->LogFile == NULL)
{
return;
}
lock = Lock((STRPTR)Globals->Settings->LogFile, ACCESS_READ);
if (lock)
{
deleteFirst = true;
UnLock(lock);
}
if (deleteFirst)
{
bool success;
LogWarning("Deleting existing log file %s", Globals->Settings->LogFile);
success = DeleteFile((STRPTR)Globals->Settings->LogFile);
if (!success)
{
char message[MAXDOSERRORLEN];
long error = IoErr();
Fault(error, (STRPTR) "Cannot delete existing log file %s", (STRPTR)message, MAXDOSERRORLEN);
LogWarning(message);
logFile = NULL;
return;
}
}
LogInfo("Opening log file %s", Globals->Settings->LogFile);
logFile = Open((STRPTR)Globals->Settings->LogFile, MODE_READWRITE);
if (!logFile)
{
char message[MAXDOSERRORLEN];
long error = IoErr();
Fault(error, (STRPTR) "Cannot open log file %s", (STRPTR)message, MAXDOSERRORLEN);
LogWarning(message);
logFile = NULL;
return;
}
}
void CloseLogFile(void)
{
if (logFile == NULL)
{
return;
}
LogTrace("Closing log file %s", Globals->Settings->LogFile);
Close(logFile);
logFile = NULL;
logDisabled = true;
}
bool TraceLogging(void)
{
return Globals->Settings->Verbose * 10 >= (int)TraceMessage
? true
: false;
}
static void VLogLine(enum LogSeverity level, const char *format, va_list ap)
{
struct LogEntry *entry;
char line[MAXLOGLINESIZE + 1];
if (logDisabled)
{
return;
}
if (bufferLog || Globals->Settings->Verbose * 10 >= (int)level)
{
int len;
VSNPrintf(line, MAXLOGLINESIZE - 1, format, ap);
len = TrimRight(line);
if (len != 0)
{
line[len++] = '\n';
line[len] = '\0';
}
}
if (bufferLog)
{
entry = (struct LogEntry *)AllocMemSafe(sizeof(struct LogEntry));
entry->level = level;
entry->line = StrDupSafe(line);
entry->next = NULL;
if (firstEntry == NULL)
{
firstEntry = entry;
lastEntry = entry;
}
else
{
lastEntry->next = entry;
lastEntry = entry;
}
return;
}
if (Globals->Settings->Verbose * 10 >= (int)level)
{
if (logFile != NULL)
{
FPuts(logFile, (STRPTR)line);
Flush(logFile);
}
else
{
Printf((STRPTR)line);
}
}
}
void LogTrace(const char *format, ...)
{
va_list args;
va_start(args, format);
VLogLine(TraceMessage, format, args);
va_end(args);
}
void LogInfo(const char *format, ...)
{
va_list args;
va_start(args, format);
VLogLine(InfoMessage, format, args);
va_end(args);
}
void LogWarning(const char *format, ...)
{
va_list args;
va_start(args, format);
VLogLine(WarningMessage, format, args);
va_end(args);
}
void LogError(const char *format, ...)
{
va_list args;
va_start(args, format);
VLogLine(ErrorMessage, format, args);
va_end(args);
}
void SetLogBuffer(void)
{
bufferLog = true;
}
void FlushLogBuffer(void)
{
struct LogEntry *current;
if (!bufferLog)
return;
current = firstEntry;
while (current != NULL)
{
struct LogEntry *last;
if (Globals->Settings->Verbose * 10 >= (int)current->level)
{
if (logFile != NULL)
{
FPuts(logFile, (STRPTR)current->line);
}
else
{
Printf((STRPTR)current->line);
}
}
last = current;
current = current->next;
FreeMemSafe(last->line);
FreeMemSafe(last);
}
bufferLog = false;
firstEntry = NULL;
lastEntry = NULL;
}