/*
* Copyright (c) 2020 Red Hat, Inc.
*
* This program 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 2
* of the License, or (at your option) any later version.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*
* $Id: //eng/uds-releases/jasper/src/uds/permassert.h#1 $
*/
#ifndef PERMASSERT_H
#define PERMASSERT_H
#include "compiler.h"
#include "errors.h"
#include "uds-error.h"
#define STRINGIFY(X) #X
#define STRINGIFY_VALUE(X) STRINGIFY(X)
/*
* A hack to apply the "warn if unused" attribute to an integral expression.
*
* Since GCC doesn't propagate the warn_unused_result attribute to
* conditional expressions incorporating calls to functions with that
* attribute, this function can be used to wrap such an expression.
* With optimization enabled, this function contributes no additional
* instructions, but the warn_unused_result attribute still applies to
* the code calling it.
*
* @param value The value to return
*
* @return The supplied value
*/
__attribute__((warn_unused_result))
static INLINE int mustUse(int value)
{
return value;
}
/*
* A replacement for assert() from assert.h.
*
* @param expr The boolean expression being asserted
* @param code The error code to return on non-fatal assertion
* failure
* @param format A printf() style format for the message to log on
* assertion failure
* @param arguments Any additional arguments required by the format
*
* @return UDS_SUCCESS If expr is true, code if expr is false and
* exitOnAssertionFailure is false. When exitOnAssertionFailure
* is true and expr is false, the program will exit from within
* this macro.
*/
#define ASSERT_WITH_ERROR_CODE(expr, code, ...) \
mustUse(__builtin_expect(!!(expr), 1) \
? UDS_SUCCESS \
: assertionFailed(STRINGIFY(expr), code, __FILE__, __LINE__, \
__VA_ARGS__))
/*
* A replacement for assert() from assert.h.
*
* @param expr The boolean expression being asserted
* @param format A printf() style format for the message to log on
* assertion failure
* @param arguments Any additional arguments required by the format
*
* @return UDS_SUCCESS If expr is true, UDS_ASSERTION_FAILED if expr is
* false and exitOnAssertionFailure is false. When
* exitOnAssertionFailure is true and expr is false, the
* program will exit from within this macro.
*/
#define ASSERT(expr, ...) \
ASSERT_WITH_ERROR_CODE(expr, UDS_ASSERTION_FAILED, __VA_ARGS__)
/*
* A replacement for assert() which logs on failure, but does not return an
* error code. This should be used sparingly. If the expression is false and
* exitOnAssertionFailure is true, the program will exit from within this macro.
*
* @param expr The boolean expression being asserted
* @param format A printf() syle format for the message to log on
* assertion failure
* @param arguments Any additional arguments required by the format
*/
#define ASSERT_LOG_ONLY(expr, ...) \
(__builtin_expect(!!(expr), 1) \
? UDS_SUCCESS \
: assertionFailedLogOnly(STRINGIFY(expr), __FILE__, __LINE__, __VA_ARGS__))
/*
* This macro is a convenient wrapper for ASSERT(false, ...).
*/
#define ASSERT_FALSE(...) \
ASSERT(false, __VA_ARGS__)
#define STATIC_ASSERT(expr) \
do { \
switch (0) { \
case 0: \
case expr: \
; \
default: \
; \
} \
} while(0)
#define STATIC_ASSERT_SIZEOF(type, expectedSize) \
STATIC_ASSERT(sizeof(type) == (expectedSize))
/**
* Set whether or not to exit on an assertion failure.
*
* @param shouldExit If <code>true</code> assertion failures will cause
* the program to exit
*
* @return The previous setting
**/
bool setExitOnAssertionFailure(bool shouldExit);
/**
* Log an assertion failure.
*
* @param expressionString The assertion
* @param errorCode The error code to return
* @param fileName The file in which the assertion appears
* @param lineNumber The line number on which the assertion
* appears
* @param format A printf() style format describing the
* assertion
*
* @return The supplied errorCode unless exitOnAssertionFailure is
* true, in which case the process will be aborted
**/
int assertionFailed(const char *expressionString,
int errorCode,
const char *fileName,
int lineNumber,
const char *format,
...)
__attribute__((format(printf, 5, 6), warn_unused_result));
/**
* Log an assertion failure. This function is different from
* assertionFailed() in that its return value may be ignored, and so should
* only be used in cases where the return value will be ignored.
*
* @param expressionString The assertion
* @param fileName The file in which the assertion appears
* @param lineNumber The line number on which the assertion
* appears
* @param format A printf() style format describing the
* assertion
*
* @return UDS_ASSERTION_FAILED unless exitOnAssertionFailure is
* true, in which case the process will be aborted
**/
int assertionFailedLogOnly(const char *expressionString,
const char *fileName,
int lineNumber,
const char *format,
...)
__attribute__((format(printf, 4, 5)));
#endif /* PERMASSERT_H */