blob: f92eadbdb4cc9a0d1bd740867b884c499cad2b1b [file] [log] [blame]
/******************************************************************************
*(C) Copyright 2008 Marvell International Ltd.
* All Rights Reserved
******************************************************************************/
/*****************************************************************************
* Utility Library
*
* DESCRIPTION
* Error reporting functions.
*
* EXAMPLE USAGE
*
* --- assert ---
*
* utlAssert(num == 42);
*
* --- reporting errors ---
*
* utlError("my error message");
*
* utlError("my error message with parameters: %d %s", 99, "my string");
*
*****************************************************************************/
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include "utlTypes.h"
#include "utlError.h"
/*---------------------------------------------------------------------------*
* FUNCTION
* utlDoAssert(utlHERE_DECLARATION, result, assertion_p)
* INPUT
* utlHERE_DECLARATION == source of assertion
* result == assertion test result
* assertion_p == assertion as a character string
* OUTPUT
* none
* RETURNS
* "true" if the assertion passed, else "false"
* DESCRIPTION
* Handles assertions, reporting an error if the assert fails.
*---------------------------------------------------------------------------*/
bool utlDoAssert(utlHERE_DECLARATION,
const int result,
const char *assertion_p)
{
if (!result)
{
/* HACK: for now just print the failed assertion... */
(void)fprintf(stderr, "ASSERT:\n");
(void)fprintf(stderr, " file path: %s\n", utlHERE_FILE);
(void)fprintf(stderr, " func name: %s\n", utlHERE_FUNC);
(void)fprintf(stderr, " line number: %u\n", (unsigned int)utlHERE_LINE);
(void)fprintf(stderr, " assertion: %s\n", assertion_p);
(void)fflush(stderr);
return false;
}
return true;
}
/*---------------------------------------------------------------------------*
* FUNCTION
* utlDoError(utlHERE_DECLARATION, msg_p, ...)
* INPUT
* utlHERE_DECLARATION == source of error
* msg_p == pointer to an error message
* OUTPUT
* none
* RETURNS
* utlSUCCESS for success, utlFAILED for failure
* DESCRIPTION
* Handles error reporting.
*---------------------------------------------------------------------------*/
void utlDoError(utlHERE_DECLARATION,
const char *msg_p,
...)
{
utlAssert(msg_p != NULL);
/* HACK: for now just print the error... */
(void)fprintf(stderr, "ERROR:\n");
(void)fprintf(stderr, " file path: %s\n", utlHERE_FILE);
(void)fprintf(stderr, " func name: %s\n", utlHERE_FUNC);
(void)fprintf(stderr, " line number: %u\n", (unsigned int)utlHERE_LINE);
(void)fprintf(stderr, " message: ");
{
va_list va_arg_p;
va_start(va_arg_p, msg_p);
(void)vfprintf(stderr, msg_p, va_arg_p);
va_end(va_arg_p);
}
(void)fprintf(stderr, "\n");
(void)fflush(stderr);
}
/*---------------------------------------------------------------------------*
* FUNCTION
* utlDoSigError(utlHERE_DECLARATION, msg_p, ...)
* INPUT
* utlHERE_DECLARATION == source of error
* msg_p == pointer to an error message
* OUTPUT
* none
* RETURNS
* utlSUCCESS for success, utlFAILED for failure
* DESCRIPTION
* Handles error reporting from with-in a signal handler.
*---------------------------------------------------------------------------*/
void utlDoSigError(utlHERE_DECLARATION,
const char *msg_p,
...)
{
char buf[200];
size_t n;
utlAssert(msg_p != NULL);
/* HACK: for now just print the error... */
/*--- accessing buffered I/O in signal handlers is not safe, so we'll do
it the hard way using only local variables and unbuffered I/O... */
n = 0;
(void)strncpy(buf + n, "SIG-ERROR:", sizeof(buf) - n); n = strlen(buf);
(void)strncpy(buf + n, "\n file path: ", sizeof(buf) - n); n = strlen(buf);
(void)strncpy(buf + n, utlHERE_FILE, sizeof(buf) - n); n = strlen(buf);
(void)strncpy(buf + n, "\n func name: ", sizeof(buf) - n); n = strlen(buf);
(void)strncpy(buf + n, utlHERE_FUNC, sizeof(buf) - n); n = strlen(buf);
(void)strncpy(buf + n, "\n line number: ", sizeof(buf) - n); n = strlen(buf);
(void)snprintf(buf + n, sizeof(buf) - n, "%u", (unsigned int)utlHERE_LINE); n = strlen(buf);
(void)strncpy(buf + n, "\n message: ", sizeof(buf) - n); n = strlen(buf);
/*--- append a formated message string ---*/
{
va_list va_arg_p;
va_start(va_arg_p, msg_p);
(void)vsnprintf(buf + n, sizeof(buf) - n, msg_p, va_arg_p); n = strlen(buf);
va_end(va_arg_p);
}
/*--- append a trailing <new-line> character ---*/
(void)strncpy(buf + n, "\n", sizeof(buf) - n); n = strlen(buf);
/*--- write output ---*/
{
char *buf_p;
ssize_t rv;
buf_p = buf;
for (; n > (size_t)0; buf_p += rv, n -= rv)
if ((rv = write(STDERR_FILENO, buf_p, n)) < (ssize_t)0)
break;
}
}
#ifdef utlTEST
/*---------------------------------------------------------------------------*
* FUNCTION
* errorTest()
* INPUT
* none
* OUTPUT
* none
* RETURNS
* "true" for pass, "false" for failure
*---------------------------------------------------------------------------*/
bool errorTest(void)
{
if (utlDoAssert(utlHERE, 1 == 1, "1 == 1") != true)
{
(void)fprintf(stderr, "errorTest: utlDoAssert(1) failed\n");
return false;
}
utlAssert(1);
if (utlDoAssert(utlHERE, 1 == 0, "1 == 0") != false)
{
(void)fprintf(stderr, "errorTest: utlDoAssert(2) failed\n");
return false;
}
utlError(errorTest, "Test message %d", 1);
utlSigError(errorTest1, "Test message %d", 2);
return true;
}
#endif /* utlTEST */