Select Git revision
fmpi_error.c
fmpi_error.c 3.13 KiB
// SPDX-License-Identifier: 0BSD
/*!
* @file
* @license{
* BSD Zero Clause License
*
* Copyright (c) 2022 by Raphael Bach
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
* }
*/
/*==============================================================================
INCLUDE
==============================================================================*/
// Own header
#include "internal/fmpi_error.h"
// C Standard Library
#include <assert.h>
#include <stdarg.h>
#include <stdio.h> // NULL, vsnprintf()
#include <time.h> // time_t, time()
/*==============================================================================
PUBLIC FUNCTION
==============================================================================*/
/*------------------------------------------------------------------------------
fmpi_raise_error()
------------------------------------------------------------------------------*/
void fmpi_raise_error(
const struct fmpi_error_handler err_handler,
const char * const file, const size_t line, const char * const func,
const char * const module, const char * const fmt, ...
){
assert(file != NULL);
assert(func != NULL);
assert(module != NULL);
assert(fmt != NULL);
if(err_handler.func == NULL) {
return;
}
const time_t t = time(NULL);
char msg_buf[FMPI_ERROR_MSG_LENGTH_MAX] = {'\0'};
const char * msg_str = "<No message>";
if(fmt != NULL) {
va_list args;
va_start(args, fmt);
const int msg_length = vsnprintf(msg_buf, sizeof(msg_buf), fmt, args);
if(msg_length < 0) {
msg_str = "<Error getting message>";
} else {
msg_str = msg_buf;
}
va_end(args);
}
err_handler.func(&(const struct fmpi_error){
.file = file,
.line = line,
.func = func,
.time = t,
.module = module,
.msg = msg_str,
},
err_handler.user_data
);
}
/*------------------------------------------------------------------------------
fmpi_error_timestamp_str()
------------------------------------------------------------------------------*/
const char * fmpi_error_timestamp_str(
const time_t t, char * const buf, const size_t size
){
assert(buf != NULL);
assert(size > 0);
if(t != -1) {
struct tm * lt = localtime(&t);
if(lt != NULL) {
const size_t byte_cnt = strftime(buf, size, "%FT%T%z", lt);
if(byte_cnt == 0) {
return NULL;
}
return buf;
}
}
return NULL;
}