Custom assert
Jump to navigation
Jump to search
Here is my custom assert
This code is for GX video only. note: after doing the below make sure you define USE_CUSTOM_ASSERT, i add -DUSE_CUSTOM_ASSERT in my makefile in the line with CFLAGS.
in your code define GXRModeObj *global_rmode; and set it to your rmode variable.
in assert.h there are two changes. The first is the prototype under the first extern "C"
the second is at bottom, the #ifdef USE_CUSTOM_ASSERT / #endif block
the below is my current assert.h, its found in devkitPro\devkitPPC\powerpc-gekko\include
since cassert includes assert.h you can include either one.
assert.h
/*
assert.h
*/
#ifdef __cplusplus
extern "C" {
#endif
void MyAssert__(const char *fn, long line);
#include "_ansi.h"
#undef assert
#ifdef NDEBUG /* required by ANSI standard */
# define assert(__e) ((void)0)
#else
# define assert(__e) ((__e) ? (void)0 : __assert_func (__FILE__, __LINE__, \
__ASSERT_FUNC, #__e))
# ifndef __ASSERT_FUNC
/* Use g++'s demangled names in C++. */
# if defined __cplusplus && defined __GNUC__
# define __ASSERT_FUNC __PRETTY_FUNCTION__
/* C99 requires the use of __func__, gcc also supports it. */
# elif defined __GNUC__ || __STDC_VERSION__ >= 199901L
# define __ASSERT_FUNC __func__
/* failed to detect __func__ support. */
# else
# define __ASSERT_FUNC ((char *) 0)
# endif
# endif /* !__ASSERT_FUNC */
#endif /* !NDEBUG */
void _EXFUN(__assert, (const char *, int, const char *)
_ATTRIBUTE ((__noreturn__)));
void _EXFUN(__assert_func, (const char *, int, const char *, const char *)
_ATTRIBUTE ((__noreturn__)));
#ifdef __cplusplus
}
#endif
#ifdef USE_CUSTOM_ASSERT
#undef assert
#define assert(e) e ? (void)0 : MyAssert__(__FILE__, __LINE__);
#endif
Thanks for dhewg for giving me this code. All i added was the extern "C" line.
log_console.h
/*-------------------------------------------------------------
Copyright (C) 2008 dhewg
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
-------------------------------------------------------------*/
#ifndef _LOG_CONSOLE_H_
#define _LOG_CONSOLE_H_
#include <gccore.h>
#ifdef __cplusplus
extern "C" {
#endif
void log_console_init(GXRModeObj *vmode, u16 logsize);
void log_console_deinit(void);
void log_console_enable_log(bool enable);
void log_console_enable_video(bool enable);
#ifdef __cplusplus
}
#endif
#endif
I added everything after /* Mavakadachi */
log_console.c
/*-------------------------------------------------------------
Copyright (C) 2008 dhewg
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
-------------------------------------------------------------*/
#include <sys/iosupport.h>
#include <reent.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "log_console.h"
static bool gecko = false;
static const devoptab_t *dot_video = NULL;
static VIRetraceCallback rcb = NULL;
static char **log = NULL;
static u16 log_size = 0;
static u16 log_next = 0;
static bool log_active = true;
static bool video_active = true;
static int __out_write(struct _reent *r, int fd, const char *ptr, size_t len) {
u16 l;
if (!ptr || len <= 0)
return -1;
if (video_active) {
dot_video->write_r(r, fd, ptr, len);
} else {
if (log_active) {
l = (log_next + 1) % log_size;
if (log[l])
free(log[l]);
log[l] = strndup(ptr, len);
log_next = l;
}
}
if (gecko)
usb_sendbuffer(1, ptr, len);
return len;
}
const devoptab_t dot_out = {
"stdout", // device name
0, // size of file structure
NULL, // device open
NULL, // device close
__out_write,// device write
NULL, // device read
NULL, // device seek
NULL, // device fstat
NULL, // device stat
NULL, // device link
NULL, // device unlink
NULL, // device chdir
NULL, // device rename
NULL, // device mkdir
0, // dirStateSize
NULL, // device diropen_r
NULL, // device dirreset_r
NULL, // device dirnext_r
NULL, // device dirclose_r
NULL // device statvfs_r
};
void log_console_init(GXRModeObj *vmode, u16 logsize) {
u16 i;
CON_InitEx(vmode, 20, 30, vmode->fbWidth - 40, vmode->xfbHeight - 60);
rcb = VIDEO_SetPostRetraceCallback(NULL);
VIDEO_SetPostRetraceCallback(rcb);
gecko = usb_isgeckoalive(1);
if (log_size && log) {
for (i = 0; i < log_size; ++i)
if (log[i])
free(log[i]);
free(log);
}
log_size = logsize;
log_next = 0;
if (log_size) {
log = (char **) malloc(log_size * sizeof(char *));
for (i = 0; i < log_size; ++i)
log[i] = NULL;
}
log_active = log_size > 0;
dot_video = devoptab_list[STD_OUT];
video_active = true;
devoptab_list[STD_OUT] = &dot_out;
devoptab_list[STD_ERR] = &dot_out;
}
void log_console_deinit(void) {
u16 i;
if (log_size && log) {
for (i = 0; i < log_size; ++i)
if (log[i])
free(log[i]);
free(log);
log = NULL;
}
log_size = 0;
log_next = 0;
devoptab_list[STD_OUT] = dot_video;
devoptab_list[STD_ERR] = dot_video;
VIDEO_SetPostRetraceCallback(rcb);
dot_video = NULL;
}
void log_console_enable_log(bool enable) {
if (!log_size)
return;
log_active = enable;
}
void log_console_enable_video(bool enable) {
struct _reent *r = _REENT;
u16 i, l;
if (video_active == enable)
return;
video_active = enable;
if (enable)
VIDEO_SetPostRetraceCallback(rcb);
else
VIDEO_SetPostRetraceCallback(NULL);
if (!enable || !log_size)
return;
for (i = 0; i < log_size; ++i) {
l = (log_next + 1 + i) % log_size;
if (log[l]) {
dot_video->write_r(r, 0, log[l], strlen(log[l]));
free(log[l]);
log[l] = NULL;
}
}
fflush(stdout);
}
/* Mavakadachi */
#include <wiiuse/wpad.h>
extern GXRModeObj *global_rmode;
void MyAssert__(const char *fn, long line)
{
log_console_init(global_rmode, 16);
log_console_enable_video(1);
log_console_enable_log(1);
printf("Assert failed in file %s on line %d\n", fn, line);
while (1)
{
WPAD_ScanPads();
if (WPAD_ButtonsDown(0) & WPAD_BUTTON_HOME)
exit(0);
VIDEO_Flush();
VIDEO_WaitVSync();
}
}