// Message handling routines
//
// Call msg to print an error message
// Call msg_set_err_mask to set which errors should be printed
// Call msg_get_err_mask to get current error mask
// Call msg_malloc to malloc with error message if fail
// Call msg_set_logfile to log fatal errors to the log file
//
// 05/17/15 DJG Added ability to log errors to a file
// 11/09/14 DJG added new msg_malloc so I don't have to keep checking return
//
// Copyright 2014 David Gesswein.
// This file is part of MFM disk utilities.
//
// MFM disk utilities 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 3 of the License, or
// (at your option) any later version.
//
// MFM disk utilities 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 MFM disk utilities. If not, see .
#include
#include
#include
#include
#include
#ifdef CLOCK_MONOTONIC_RAW
#define CLOCK CLOCK_MONOTONIC_RAW
#else
#define CLOCK CLOCK_MONOTONIC
#endif
#include "msg.h"
// Current error mask. Not thread safe for changes
static uint64_t err_mask = 0xffffffff;
// If not null log fatal errors to file
static FILE *logfile = NULL;
uint32_t logfile_err_mask;
// Print an error message.
//
// level: Error level used to determine if message should be printed
// format: Format string for message
//
void msg(uint32_t level, char *format, ...) {
static int last_progress = 0;
va_list va;
va_start(va, format);
if (err_mask & level) {
// Overwrite progress message with spaces in case new message is shorter
if (last_progress && !(level & MSG_PROGRESS)) {
printf("%79s\r","");
}
vprintf(format, va);
if (level & MSG_PROGRESS) {
fflush(stdout);
}
last_progress = level & MSG_PROGRESS;
}
if (logfile != NULL && (level & logfile_err_mask)) {
vfprintf(logfile, format, va);
}
va_end(va);
}
// Set the error mask and get previous value
//
// mask: New error mask
// return: Previous error mask
uint32_t msg_set_err_mask(uint32_t mask) {
uint32_t last_mask;
last_mask = err_mask;
err_mask = mask;
return last_mask;
}
// Get the error mask
// return: Current error mask
uint32_t msg_get_err_mask(void) {
return err_mask;
}
// Malloc and print error if fail
//
void *msg_malloc(size_t size, char *msgstr) {
void *ptr;
ptr = malloc(size);
if (ptr == NULL) {
msg(MSG_FATAL,"Malloc failed %s size %u\n", msgstr, size);
exit(1);
}
return ptr;
}
// Set logfile to log selected errors to
// file: File descriptor to write messages to
// mask: Error mask for errors to log
void msg_set_logfile(FILE *file, uint32_t mask) {
logfile = file;
logfile_err_mask = mask;
}